I have two React Components, Header (with input) and Search.
How I can access 'userInput' from Search Component?
Header Component
import React, {useState} from 'react';
const Header = () => {
const [userInput, setUserInput] = useState('');
const inputchangehandler = (event) => {
setUserInput(event.target.value)
}
return (
<div className="header">
<input type="text" name="nome" onChange={inputchangehandler} value={userInput} />
</div>
)
}
Search Component
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
const Search = () => {
//const { word } = useParams();
const dispatch = useDispatch();
const word = useSelector(state => state.userInput);
useEffect(() => {
console.log(userInput);
dispatch(fetchAsyncMoviesSearch(word ));
}, [dispatch, word])
return (
<div>
<MovieListing />
</div>
)
}
CodePudding user response:
If you are already using redux, I think it is easier to handle the userInput with it instead of useState in this situation.
So you can create the userInput redux state and the setUserInput redux action, as well. Something like this:
Header component
const Header = () => {
const dispatch = useDispatch();
const userInput = useSelector(state => state.userInput)
const inputchangehandler = (event) => {
dispatch(setUserInput(event.target.value))
}
return (
<div className="header">
<input type="text" name="nome" onChange={inputchangehandler} value={userInput} />
</div>
)
}
Search component
const Search = () => {
const dispatch = useDispatch();
const word = useSelector(state => state.userInput);
useEffect(() => {
dispatch(fetchAsyncMoviesSearch(word ));
}, [dispatch, word])
return (
<div>
<MovieListing />
</div>
)
}
CodePudding user response:
Since you are using Redux for state sharing between components, it's best to have a Redux action that dispatches the userInput
to store from Header
component when user types in the search, then access userInput
from Search
component later using useSelector()
.
The core idea is dispatching an action that contains user input value to Redux store.
Your custom updateSearchInput
Redux action can look like this:
// assuming that you have it in ./customReduxActions.js file
// ...
export const updateSearchInput = (keyword) => ({
type: 'update-search-input',
payload: keyword,
});
// ...
Then your Redux store needs to be able to process this action:
switch (action.type) {
// ... other actions
case 'update-search-input':
return {
...state,
userInput: action.payload
};
// ... other actions
}
After this, when you access state.userInput
using useSelector()
you should be able to get the input value from Redux store across components.
Your Header
component then can look like this:
// Your custom action written above
import { updateSearchInput } from './customReduxActions';
const Header = () => {
const dispatch = useDispatch();
const userInput = useSelector(state => state.userInput);
const inputChangeHandler = (event) => {
const keyword = event.target.value;
// this dispatch() call is most important
dispatch(updateSearchInput(keyword));
};
return (
<div className="header">
<input
type="text"
name="nome"
onChange={inputChangeHandler}
value={userInput}
/>
</div>
)
}
Your Search
component remains the same with no changes:
const Search = () => {
const dispatch = useDispatch();
// access state.userInput from Redux store as expected behavior
const word = useSelector(state => state.userInput);
useEffect(() => {
dispatch(fetchAsyncMoviesSearch(word));
}, [dispatch, word])
return (
<div>
<MovieListing />
</div>
)
}