I have a page and that page has two components. I am fetching the data from root component and passing data to child component using react-redux
. I tried to set the fetched data to a state variable that is in child component but it sets data before the fetch is complete in the root component. So, I am getting blank object.
// child component const [myData, setMyData] = useState<any>(null); const data = useSelector((state: { value: any }) => state.value); useEffect(() => { setMyData(data); }, []);
// parent component const dispatch = useDispatch(); useEffect(() => { fetch(url) .then((response) => response.json()) .then((data) => { dispatch(setData(data)); }); }, []);
You can check the whole codebase : https://github.com/Sadiq1029/weather
Can someone help?
Advertisement
Answer
Check if data
is not null then update your child state
useEffect(() => { if (data) setMyData(data); }, [data ]);
data.ts
import { createSlice, createSelector } from "@reduxjs/toolkit"; export const dataSlice = createSlice({ name: "data", initialState: { value: null }, reducers: { setData: (state, action) => { state.value = action.payload; }, }, }); export const { setData } = dataSlice.actions; const selectDataSlice = (state: any) => state.data export const selectValue = createSelector(selectDataSlice, (state) => state.value) export default dataSlice.reducer;
Background.tsx
import { Container, Flex, Text } from "@chakra-ui/react"; import type { NextPage } from "next"; import { useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { selectValue } from "../../states/data"; const Background: NextPage = () => { const [myData, setMyData] = useState<any>(null); const data = useSelector(selectValue); useEffect(() => { if (data) { setMyData(data); } }, [data]); return ( <Flex minW="100vw" minH="100vh" alignItems="flex-end" style={{ background: `url('/images/background.jpg') center no-repeat`, backgroundSize: "cover", }} > <Flex id="stats" m="8" flexDirection="column" color="white"> <Text fontSize="xl" fontWeight="hairline"> {myData ? myData.name : ""} {/* {data ? data.name : "hi"}, {data ? data.sys.country : "_"} */} </Text> <Text fontWeight="bold" fontSize="8xl"> {/* {data ? Math.round(data.main.temp) : "0"}°C */} </Text> {/* <Text>{data ? data.weather[0].main : ""}</Text> */} </Flex> </Flex> ); }; export default Background;