0

I was trying to control a Material-UI drawer by using RTK status, this is my component:

export default function NavToolbar(props) {
  const dispatch = useDispatch();
  const nodeDrawerOpened = useSelector(
    state => state.componentStatus.leftDrawerOpened
  );
  const nodeDrawerOpenHandler = (status)=> {
    dispatch(setLeftDrawerOpen(!status));
  };

  return (
    <>
      <Box variant="" className={styles.cntrToolBar}>
        <Grid
          container
          columns={24}
          direction="row"
          justifyContent="center"
          alignItems="center"
        >
          <Grid item xs={1}>
            <Box className={styles.cntrToolBarLeftTools}>
              <IconButton className={styles.toolBarIconBtn}>
                <ListIcon/>
              </IconButton>
            </Box>
          </Grid>
          <Grid item xs={20}>
            <Progressbar/>
          </Grid>
          <Grid item xs={3}>
            <Box className={styles.cntrToolBarRightTools}>
              <IconButton
                className={styles.toolBarIconBtn}
                onClick={() => nodeDrawerOpenHandler(nodeDrawerOpened)}>
                <SimCardDownloadOutlinedIcon />
              </IconButton>
            </Box>
          </Grid>
        </Grid>
      </Box>
    </>
  )
}

It didn't work as I thought.

Then I tried to remove the props for nodeDrawerOpenHandler and pass the nodeDrawerOpened directly to dispatch function and it worked well. Like this:

export default function NavToolbar(props) {

  const dispatch = useDispatch();
  const nodeDrawerOpened = useSelector(
    state => state.componentStatus.leftDrawerOpened
  );

  // **
  const nodeDrawerOpenHandler = ()=> {
    dispatch(setLeftDrawerOpen(!nodeDrawerOpened));
  };

  return (
    <>
      <Box variant="" className={styles.cntrToolBar}>
        <Grid
          container
          columns={24}
          direction="row"
          justifyContent="center"
          alignItems="center"
        >
          <Grid item xs={1}>
            <Box className={styles.cntrToolBarLeftTools}>
              <IconButton className={styles.toolBarIconBtn}>
                <ListIcon/>
              </IconButton>
            </Box>
          </Grid>
          <Grid item xs={20}>
            <Progressbar/>
          </Grid>
          <Grid item xs={3}>
            <Box className={styles.cntrToolBarRightTools}>
              <IconButton
                className={styles.toolBarIconBtn}
                onClick={() => nodeDrawerOpenHandler()}> // **
                <SimCardDownloadOutlinedIcon />
              </IconButton>
            </Box>
          </Grid>
        </Grid>
      </Box>
    </>
  )
}

I know the status from redux are rendered asynchronously, but what is the theory behind my example? Can someone explain this to me with some details? What is the difference of these two ways?

3
  • This is my reducer: setLeftDrawerOpen: (state, action)=>{ state.leftDrawerOpened = action.payload; }, Commented Mar 5, 2024 at 15:46
  • I don't see much of a difference between the two, I think they both should work. I'm also wondering why you didn't just make an action to toggle the drawer, e.g. toggleLeftDrawerOpened: state => { state.leftDrawerOpened = !state.leftDrawerOpened; },, and then do don't need to select the state and worry about correct Javascript closures to get the correct toggleable value in there on the UI side. Commented Mar 5, 2024 at 16:19
  • @DrewReese Thanks for the good advice! It is a good way to avoid this kind of problem. I just tried to reproduce the problem but failed. But in the end it is kind of solved. Still no clue what happend in the code yesterday though... Commented Mar 6, 2024 at 7:31

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.