I have a function in the that fetches the weather data for current location when button is clicked. I want to get this data from the Location component to the pages/index.tsx where I have another components that displays that data.
This is my component structure:
App
--Layout
--Header
--Location (here i fetch the data on click)
--Home (state)
--Display 1
--SubDisplay 1
--Display 2
Do I have to pass the data through all the components to the index page? It would be:
- UP from Location to Header
- UP from Header to Layout
- DOWN from Layout to Index page
- DOWN from Index page to another components
Is this the best way to handle this?
CodePudding user response:
Due to React's nature regarding data flow, you can only pass props
down from parent component to its children, this is known as one-way data binding or unidirectional data flow. Based on the structure of your components, to achieve what you want to do you would need to use Context
API or something like redux
to centralize your data in one place (or just lifting the states up). However you can try this "workaround" so you don't need to modify your project's structure:
Since your state is in the index/home page, you could define a function in this component that will receive as parameter the data fetched in Location
component and set the state with this data, of course you'd need to pass this function via props
to Layout
component so it can pass it to Header
and Header
to Location
(prop drilling), example:
const Home = () => {
const [data, setData] = useState([]);
const handleData = (data) => {
setData(data);
}
return (
<Layout handleData={handleData}>
The rest of your components...
</Layout>
)
}
Then like I said, pass that function this way: Layout - Header - Location.
In Location
:
const Location = ({ handleData }) => {
const handleClick = () => {
// Fetch your data on click event and pass it as parameter to handleData function
handleData(fetchedData);
}
// The rest of your component...
}
Hope this helps you.
CodePudding user response:
Suggested solutions based on more complexity
Lifting state up (Easier than other) sample code
- Define shipping function and weatherData as a state in Layout Component, then send shippingFunction into Header component then Location component as prop
const [weatherData,setWeatherData]=useState();
const shippingFunction = function(data) { setWeatherData(data);}
Location Component
- Call props.shippingFunction in Layout component when weather data was fetched, then send weather data into props.shippingFunction as parameter. Now you have weather data in Layout component
Layout Component
- At this moment you have filled weatherData and you can pass it as prop into any component you want