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?
CodePudding user response:
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;