unable to update the state through custom react hook Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of unable to update the state through custom react hook without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I am trying to create a custom hook which returns a custom drawer and a button(to toggle the state of drawer). I am managing the state in custom hook itself.

This is my custom hook for returning the drawer and a button

import React from "react";
import clsx from "clsx";
import { makeStyles } from "@material-ui/core/styles";
import Drawer from "@material-ui/core/Drawer";
import List from "@material-ui/core/List";
import Divider from "@material-ui/core/Divider";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import MailIcon from "@material-ui/icons/Mail";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBars } from "@fortawesome/free-solid-svg-icons";
import { Button } from "@material-ui/core";

const useStyles = makeStyles({
  list: {
    width: 250
  },
  fullList: {
    width: "auto"
  }
});

export default function useTemporaryDrawer(toggle) {
  const classes = useStyles();

  const [state, setState] = React.useState({
    right: false
  });

  const toggleDrawer = (anchor, open) => (event) => {
    if (
      event.type === "keydown" &&
      (event.key === "Tab" || event.key === "Shift")
    ) {
      return;
    }
    alert("setting");
    setState({ ...state, [anchor]: open });
  };

  const onButtonClick = (e) => {
    toggleDrawer("right", true)(e);
  };

  const Toggler = (
    <Button
      style={{
        marginTop: "10px"
      }}
      onClick={onButtonClick}
      startIcon={<FontAwesomeIcon icon={faBars} style={{ color: "#fff" }} />}
    ></Button>
  );

  const list = (anchor) => (
    <div
      className={clsx(classes.list, {
        [classes.fullList]: anchor === "top" || anchor === "bottom"
      })}
      role="presentation"
      onClick={toggleDrawer(anchor, false)}
      onKeyDown={toggleDrawer(anchor, false)}
    >
      <List>
        {["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
          <ListItem button key={text}>
            <ListItemIcon>
              {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
            </ListItemIcon>
            <ListItemText primary={text} />
          </ListItem>
        ))}
      </List>
      <Divider />
      <List>
        {["All mail", "Trash", "Spam"].map((text, index) => (
          <ListItem button key={text}>
            <ListItemIcon>
              {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
            </ListItemIcon>
            <ListItemText primary={text} />
          </ListItem>
        ))}
      </List>
    </div>
  );

  const CustomDrawer = (
    <Drawer
      anchor={"right"}
      open={state["right"]}
      onClose={toggleDrawer("right", false)}
    >
      {list("right")}
    </Drawer>
  );

  return {
    CustomDrawer,
    setState,
    state,
    Toggler
  };
}

Then, I am trying to update the state through Toggle button which I am using in Header. This is my header

import React from "react";
import styles from "./Header.module.css";
import useTemporaryDrawer from "../Drawer/useTemporaryDrawer";

const Header = (props) => {
  const { Toggler } = useTemporaryDrawer();

  return <div className={styles.headerForApp}>{Toggler}</div>;
};

export default Header;

When I press the toggle button, it does update the state but it does not update the open property of drawer. In short I am not able to open the drawer through toggle button. Please help.

Here is the sandbox https://codesandbox.io/s/customhooksnotupdatingstate-d7mfz?file=/src/components/Drawer/useTemporaryDrawer.js

Answer

If I have 2 components: A and B, and each of them have setState hook to update variable state, you won’t expect setState('a') inside A to make any difference to state in B, will you? But then you create 2 components, each of them with their independent state and expect those states to be shared somehow. Toggle in Header changes state of Header, and Drawer in Dashboard had no visibility of these changes. As an option you can pass Toggler to the Header as a prop

<Header Toggler={Toggler} />
const Header = (props) => {
return <div className={styles.headerForApp}>{props.Toggler}</div>;
};
We are here to answer your question about unable to update the state through custom react hook - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji