I cannot toggle my boolean value in Redux

Viewed 28

I am working on an anime project. My problem is that when I click the input, I want to bring it to the forefront. So, I used "webkitRequestFullscreen()", but I cannot toggle my boolean to true in order to make it. I looked for some solutions, but I guess, the version I use for Redux is different from theirs and I didn't understand them.

Here is my initial state and reducer function:

const initialState = {
  items: [],
  fullScreen: false,
}
reducers: {
    toggleInputScreen: (state, action) => {
      const id = action.payload
      state.fullScreen = !state.fullScreen
    },
  },

The main component:

let activeFullScreen = useSelector((state) => state.anime.fullScreen)
  // console.log(activeFullScreen)

  if (activeFullScreen) {
    return inputRef.current.webkitRequestFullscreen()
  }
<div
    className="input-container"
    onClick={() => dispatch(toggleInputScreen())}
    id="input-div">
    <input type="search" placeholder="Search..." ref={inputRef} />
</div>

I know the reducer function is a total disaster. How can I toggle the fullScreen boolean when I click the input? Thanks in advance.

1 Answers

The problem is probably the reducer function.

In Redux, the state is immutable, which means you never modify the state, instead, create a new copy. Another mistake is, that you have to return the new state in the reducer function.

Reducers are functions that take the current state and an action as arguments, and return a new state result. [...] They are not allowed to modify the existing state. Instead, they must make immutable updates, by copying the existing state and making changes to the copied values. - redux guide

You can solve your problem by following the just appointed rules:

toggleInputScreen: (state, action) => {
  const id = action.payload
  //create and return a new object, which is the new state
  return {
    items: state.items,
    fullScreen: !state.fullScreen,
  }
}

If the state is an object and grows in size, you can use the Object.assign() method to create a copy of the object and change values of it easily. Check it out here and here. For redux you would use the following schema: Object.assign({}, state, changes). In you case, that would look like this:

toggleInputScreen: (state, action) => {
  const id = action.payload
  //create and return a new object, which is the new state
  return Object.assign({}, state, { fullscreen: !state.fullscreen }); 
}
Related