How to avoid duplicate image urls on click in Redux

109
August 11, 2021, at 8:20 PM

I'm working on a React-Redux app.

I fetch a random image URL from Unsplash API and have two options: approve it or reject. onApprove the image lands into a gallery.

I noticed that if I click onApprove button quickly multiple times, then I put duplicate images into my gallery. I know that in React you can do something like this to be able to handle actions

setState(prevState) => {return prevState + 1} 

But here comes Redux. I use createSlice() to take care of the reducers. Here is the code snippet with the functionality

const imagesSlice = createSlice({
  name: 'images',
  // The intial state value we pass for the reducers. A state the first time it gets called.
  initialState,
  reducers: {
    imageApproved(state, action) {
      state.approvedImageList.push(action.payload);
    },
  },
});

And later on I dispatch an action in my Footer where buttons are:

function Footer({ randomImageUrl, generateNewRandomImage }) {
  const dispatch = useDispatch();
  function onApprove() {
    dispatch(imageApproved(randomImageUrl));
    generateNewRandomImage();
  }

  const showButton = useSelector((state) => state.buttons.showButton);
  return (
    <FooterWrapper>
      {showButton ? (
        <FooterCopy>
          Click on the + in order to get image recommendations
        </FooterCopy>
      ) : (
        <ButtonWrapper>
          <Button bgColorOnHover='true' onClick={onApprove}>
            APPROVE
          </Button>
        </ButtonWrapper>
      )}
    </FooterWrapper>
  );
}

So how can I avoid duplicating images onClick? Thanks!

PLUS: I've got a question:

when I fetch data from the API, I only fetch the imageUrl. That means that I am not checking Ids in my code, but only imageUrls. Idk if it could be the reason for the duplicates as well, but do I have to fetch the Ids and check them with .includes() as well?

Answer 1

You can check new Url in the approvedImageList or not before push:

imageApproved(state, action) {
  const url = action.payload;
  if(!state.approvedImageList.includes(url)){
    state.approvedImageList.push(url);
  }
},
Answer 2

nothing redux-specific here:

    imageApproved(state, action) {
      if (!state.approvedImageList.includes(action.payload)) {
        state.approvedImageList.push(action.payload);
      }
    },
Rent Charter Buses Company
READ ALSO
Clean code best practice in PHP. Less DB calls or friendlier code [closed]

Clean code best practice in PHP. Less DB calls or friendlier code [closed]

Want to improve this question? Update the question so it can be answered with facts and citations by editing this post

152
Upgrade python version in GCP Composer

Upgrade python version in GCP Composer

We have a GCP composer with Python version 3I would like to update the version to Python 3

154
How to combine a front-end library and Node tool in one package without front-end bloat?

How to combine a front-end library and Node tool in one package without front-end bloat?

I have two libraries which I'm considering combining into oneOne is a front-end library (although it can be used in Node), the other is a command-line tool, with some Node dependencies

157
Group numbers from array that are right after each other [closed]

Group numbers from array that are right after each other [closed]

Want to improve this question? Update the question so it focuses on one problem only by editing this post

189