Home > Software design >  React Redux is not updating component state in real time
React Redux is not updating component state in real time

Time:07-11

I have one component ImageGallery, in there I want to load more images after pressing Load More button. And, loadMore() function updates a react-redux globalState.js initialState value limit. But, When I am pressing Load More button I have to press 2 times for the first time to get the first 16 images. After that it's updating value as expected. But, first time I have to press 2 times. But, I want, it will work on first time click and get 16 items and so on.

globalState.js:

export const globalState = createSlice({
  name: "global",
  initialState: {
  limit: 8
  }
  reducers: {
    // imageGallery
    incrementLimitGallery: (state) => {
      state.limit  = 8;
    },
   },
});

Component ImageGallery.jsx:

let API = "https://www.example.com/images/";

export default function ImageGallery() {
  const dispatch = useDispatch();
  const limit = useSelector((state) => state.global.limit);
  const [images, setimages] = useState(null);

  async function fetchImages() {
    const response = await axios.get(API   limit);
    if ("error" in response.data) {
      setimages(null);
    } else {
      setimages(response.data);
    }
  }

  const loadMore = async () => {
    dispatch(incrementLimitGallery());
    await fetchImages();
  };

  return (
    <>
     //implementation of image gallery, long code so hide it
      <div>{images ? (imgaes.map(image => (.......))): null}</div>

      <div>
        <button onClick={() => loadMore()}>Load More</button>
      </div>
    </>
  );
}

CodePudding user response:

Your code will not work because it runs asynchronously so when you call fetchImages state hasn't been updated yet.

What I would propose is to use fetchImages inside a useEffect function which is dependent on limit.

loadMore on the other hand will trigger the redux state update and especially the limit update so then useEffect will run again.

  const loadMore = () => {
    dispatch(incrementLimitGallery());
  };

and something like this

useEffect(() => {
  fetchImages();
}, [limit]);

CodePudding user response:

You can modify your loadmore function like this :

const loadMore = async () => {
    dispatch(incrementLimitGallery())
    .then(()=>{
        await fetchImages();
     });
  };

As the problem is, your redux state is not updated when you are fetching the images after the distpatch function(as dispatch is an async task). So you can run fetchImages function when the redux state is updated. Use .then method to implement the logic, as shown above.

  • Related