Search code examples
reactjsreact-hooksreact-lifecycle

prevent re render with hooks


I'm handle a toggle button status which is inside a table.. when request to api fail i need to return an error and the checked status can't change.

Checked is controlled by a specific data from api.. What is happening is, when setErrors the component is re render which I believe is the cause of toggle button changing.

 async function handleStatus(groups, status, id) {
    const response = await chengeStatus(groups, status, id);
    const { status: state, data, message } = response;

    if (state) {
      setGroups(data);
      return true;
    } else {
      setErrors({
        status: true,
        message: message,
      });
      return false;
    }
  }

Toggle Button :

const columns = [
    {
      cell: (row) => {
        return (
          <Switch
            checked={row.enable}
            handleChange={() => handleStatus(groups, row.enable, row.id)}
          ></Switch>
        );
      },
      width: "80px",
    },
  ];

Error display:

 return(
     {errors.status &&
      <Alert
      message="Erro"
      description={errors.message}
      type="error"
      showIcon
      />
      } 
    )

Solution

  • It is not a good idea to solving this by preventing re-render.

    What you need to do should change checked={row.enable} to defaultChecked={row.enable}

    pass the default value to and create another hook for the real checked state:

    const Switch = ({ defaultChecked, handleChange }) => {
      const [checked, setChecked] = useState(defaultChecked);
    
      useEffect(() => {
    
        setChecked(defaultChecked);
    
      }, [defaultChecked]); // Update the state if props change again.
    
      const onToggle = () => {
        handleChange(!checked);
        setChecked(!checked);
      }
    
      return <Comp checked={checked} onToggle={onToggle} />; // TODO show you the idea only
    }
    

    so checked value will remain unchanged after clicked until you refetch row data.