How to load UI after data is updated in useEffect in react native

Viewed 715

I am using useEffect to save all the data coming from redux in a state.

Below is my code:

const [items, setItems] = useState();
React.useEffect(() => {
    setItems(createMenuReducer.data.product);
    console.log("item", items);
}, [items]);

<ScrollView>
    {createMenuReducer &&
        items?.map((item, index) => {
            return (
                <ItemComponent
                    item={item}
                />
            );
        })}
</ScrollView>

console.log output:

item undefined

but when I click save again then all the items are getting consoled:

item (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

I tried to update state, thinking it will also update the UI, but that is not happening. I am getting a blank page when loads first time, but when I click save again, all the items are shown in UI. How to fix this so that all the items are on the screen when the app loads??

1 Answers

Do know that state updates are affected by closures and are async so your items value will not be consoled immediately after calling setItems, however it will be available in next render.

Also note that you must update your items when the createMenuReducer data updates and hence add that as a dependency to useEffect instead of items

const [items, setItems] = useState([]);
React.useEffect(() => {
    setItems(createMenuReducer.data.product);
}, [createMenuReducer?.data.product]);

console.log(items);

<ScrollView>
    {items.map((item, index) => {
            return (
                <ItemComponent
                    item={item}
                />
            );
        })}
</ScrollView>

However in most cases you shouldn't need to copy props value to state and should directly use the data from props

<ScrollView>
        {createMenuReducer?.data?.product?.map((item, index) => {
                return (
                    <ItemComponent
                        item={item}
                    />
                );
            })}
    </ScrollView>
Related