0

I have a component on a page that renders a bunch of checkboxes and toggles.

I also have a button called confirm at the bottom to save the changes and make a request to update the back-end.

However I wanted to support a feature that when users haven't made any changes to any of these checkboxes or toggles, the confirm button should be disabled. and when users toggle or check any of these, then the confirm button is enabled and clickable.

so right now what I am doing is

const MyComponent = () => {
  const dispatch = useDispatch();
  // get the current state from the store
  const state = useSelector((state: RootState) => state.settings);

  const [isCheckbox1Checked, setCheckbox1] = useState(false);
  const [isCheckbox2Checked, setCheckbox2] = useState(false);
  const [isCheckbox3Checked, setCheckbox3] = useState(false);
  const [isConfirmBtnEnabled, setConfirmBtn] = useState(false);


  const [updateBtnEnabled, enableUpdateBtn] = useState(false);

  useEffect(() => {
    (async () => {
      // `getSettingsConfig` is a async thunk action
      await dispatch(getSettingsConfig());

      setCheckbox1(state.isCheckbox1Checked);

      setCheckbox2(state.isCheckbox2Checked);

      setCheckbox3(state.isCheckbox3Checked);
    })();
  }, [
    dispatch,

    state.isCheckbox1Checked,

    state.isCheckbox2Checked,

    state.isCheckbox3Checked
    // ..
  ]);

  return (
    <>
      <div className="checkboxes">
        <Checkbox1
          onCheck={() => {
            setCheckbox1(true);
            setConfirmBtn(true);
          }}
        />
        <Checkbox2
          onCheck={() => {
            setCheckbox2(true);
            setConfirmBtn(true);
          }}
        />
        <Checkbox3
          onCheck={() => {
            setCheckbox3(true);
            setConfirmBtn(true);
          }}
        />
      </div>
      <button disabled={!isConfirmBtnEnabled}>Confirm</button>
    </>
  );
};

right now it seems to be working out fine but it requires manually spamming setConfirmBtn to every checkbox and toggles I have on this page. I wonder if there is a better way to do it.

Also I thought about using useEffect to call isConfirmBtnEnabled every time any of these state changes. However since the initial state is derived from the store via dispatching an async thunk, the state of these checkboxes and toggles are going to be changed anyways after the page mounts, so that means I cannot use another useEffect to listen on the changes of these state.

1 Answer 1

1

You could use useEffect hook to watch the three check boxes and update the button state based on isConfirmBtnEnabled which is updated inside the useEffect hook:

useEffect(()=>{

   setConfirmBtn(isCheckbox1Checked || isCheckbox2Checked || isCheckbox3Checked)

},[isCheckbox1Checked,isCheckbox2Checked,isCheckbox3Checked])

Edit :


const MyComponent = () => {
  const dispatch = useDispatch();
  // get the current state from the store
  const state = useSelector((state: RootState) => state.settings);

  const [checkboxes, setCheckboxes] = useState({c1:false,c2:false,c3:false});
  const [isConfirmBtnEnabled, setConfirmBtn] = useState(false);


  const [updateBtnEnabled, enableUpdateBtn] = useState(false);

  useEffect(() => {
    (async () => {
      // `getSettingsConfig` is a async thunk action
      await dispatch(getSettingsConfig());
  [1,2,3].forEach(i=>{
        setCheckboxes({...checkboxes,[`c${i}`]:state[`isCheckbox${1}Checked`]})
      })
    
    })();
  }, [
    dispatch,

    state
    // ..
  ]);

   useEffect(()=>{
    setConfirmBtn(Object.values(checkboxes).reduce((a,c)=>(a=a || c),false))
   },[checkboxes])
  const _onCheck=(i)=>{
 setCheckboxes({...checkboxes,[`c${i}`]:tur})
   }
  return (
    <>
      <div className="checkboxes">
        <Checkbox1
          onCheck={() => _onCheck(1)}
        />
        <Checkbox2
         onCheck={() => _onCheck(2)}
        />
        <Checkbox3
          onCheck={() => _onCheck(3)}
        />
      </div>
      <button disabled={!isConfirmBtnEnabled}>Confirm</button>
    </>
  );
};

Sign up to request clarification or add additional context in comments.

9 Comments

Hi thanks for the reply. I actually thought of this approach but it doesn't seem to be working with my situation. sorry I didn't explain the situation clearly enough. I edited my post.
the redux state has only the three values (isCheckbox3Checked,isCheckbox1Checked,isCheckbox3Checked)?
no it has a lot more I am just trying to simplify it here
ok, i recommend instead of using three states for each checkboxe use one like const [checkboxes, setCheckboxes] = useState({c1:false,c2:false,c3:false}); then in check event setCheckboxes({...checkboxes,c1:true}) in order to enable the button watch one dependency checkboxes and update isConfirmBtnEnabled inside the useeffect like setConfirmBtn(checkboxes.reduce((a,c)=>(a=a || c),false))
please check the edited answer i think you didn't understand my ugly comment above
|

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.