I'm calling data with a useEffect like this:
useEffect(() => {
fetchData(id);
}, []);
Then fetching data and updating state with useReducer dispatch like this:
const fetchData = dispatch => async props => {
const id = props;
await axios
.get(`${URL}?id=${id}`)
.then(res => {
const data = res.data;
const isAuth = data[0].isAuth;
const dataDetails = data[1].dataDetails;
const dataTracks = data[2].dataTracks;
dispatch({type: 'dataDetails', payload: dataDetails});
dispatch({type: 'dataTracks', payload: dataTracks});
dispatch({type: 'isAuth', payload: isAuth});
});
};
Then rendering data like this:
return (
<SafeAreaView >
<View >
{state.dataDetails ? (
<Text>
{'@' state.dataDetails.username}
</Text>
) : null}
<View/>
</View>
<View >
<FlatList
data={state.dataDetails.Tracks}
ListHeaderComponent={ <DataDetails />}
renderItem={({item}) => <PostTracks item={item} />}
></FlatList>
</View>
</SafeAreaView>
);
I'm suppose to display username that i'm getting from data in a header and displaying the rest of the data in a Flatlist but it's not rendering anything.
When I console.log data it first returns undefined, then returns data
How can I make it so that it waits for data to load before it renders the screen?
CodePudding user response:
I think you need create a loading, like this:
const [loading, setLoading] = useState()
In your useEffect
:
useEffect(() => {
fetchData(id);
}, [id]);
In fetchData
function, you will change loading
variable, like this:
const fetchData = dispatch => async props => {
setLoading(true);
const id = props;
await axios
.get(`${URL}?id=${id}`)
.then(res => {
const data = res.data;
const isAuth = data[0].isAuth;
const dataDetails = data[1].dataDetails;
const dataTracks = data[2].dataTracks;
dispatch({type: 'dataDetails', payload: dataDetails});
dispatch({type: 'dataTracks', payload: dataTracks});
dispatch({type: 'isAuth', payload: isAuth});
setLoading(false)
});
};
Afterward, you use loading
to render the screen:
return (
{
loading ? <>loading</>
: <SafeAreaView >
<View >
{state.dataDetails ? (
<Text>
{'@' state.dataDetails.username}
</Text>
) : null}
<View/>
</View>
<View >
<FlatList
data={state.dataDetails.Tracks}
ListHeaderComponent={ <DataDetails />}
renderItem={({item}) => <PostTracks item={item} />}
></FlatList>
</View>
</SafeAreaView>
}
);
You can try change this way.
CodePudding user response:
Put your id
in dependency array:
useEffect(() => {
fetchData(id);
}, [id]);
Since your dependency array is empty, the useEffect
only runs once.
If you put your variable in dependency array, the useEffect
will run again when variable changed. Thus, the view will re-render.