2

enter image description here

I want to call a post API while changing the checkbox input. Right now I am doing this in the below pattern but while the Component re-renders, this API function got called. What to do, please?

 const [check, setCheck] = useState();
 
  async function fetchConfigApi() {
    try {
       const result = await axios.get(`/configuration/${system_id}`);
       const { status, data } = result;
       setConfigData(data);
       setCheck(data.self_service);
    } catch (e) {
      console.log("error response", e.response);
    }  
  }

  async function postSelfService() {
   try {
      const fd = new FormData();
      fd.append("self_service", check);
      const result = await axios.put(`/configuration/${system_id}`, fd);
      fetchConfigApi();
    } catch (e) {
      console.log("error response", e.response);
    }   
  }  

  const onSelfServiceChange = (e) => { setCheck(!check); };

  useEffect(() => { fetchConfigApi(); }, []);

  useEffect(() => { postSelfService(); }, [check]);

return (
    <div className={classes.subContainer}>
        <div>
          <FormControlLabel
            control={
               <Checkbox
                checked={check}
               onChange={onSelfServiceChange}
                 name="check"
               />
             }
             label="Enable Self Service"
           />    </div> )

1 Answer 1

2

Just remove the second useEffect and put your API call inside onChange function like this:

For a better user experience and void unnecessary calls, you should add a loading state when the user clicks on the checkbox that gets disabled while fetching the result, then checked or unchecked based on the response.

const App = () => {
  const [data, setConfigData] = React.useState(false);
  const [check, setCheck] = React.useState(false);
  const [loading, setLoading] = React.useState(true);

  function fetchConfigApi() {
    try {
      // simulate api call
      setTimeout(()=> {
        setConfigData("new data on: "+ new Date() )
        setCheck(prev=>!prev);
        setLoading(false);
      },500)
    } catch (e) {
      console.log("error response", e.response);
    }
  }

  function postSelfService() {
    try {
      // simulate api call
      setTimeout(()=> fetchConfigApi(),500)
    } catch (e) {
      console.log("error response", e.response);
    }
  }

  const onSelfServiceChange = (e) => {
    setLoading(true);
    postSelfService();
  };

  React.useEffect(() => {
    fetchConfigApi();
  }, []);

  return (
    <div>
        <label>
          <input
            type="checkbox"
            checked={check}
            onChange={onSelfServiceChange}
            name="check"
            disabled={loading}
          />
          Enable Self Service 
        </label>
        <hr/>
        <p>{loading ? "loading..." : data}</p>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

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

4 Comments

initially i have tried it but the propblem is when i am getting this check data from api and put it in my checkbox its alwas showing cheked. But when i am checking and adding another save button to hit the post api its working fine. Let me know if u know issue. Thanx
Oh true, I see we call setCheck twice. I did make my answer better by adding a loading state when the user clicks on the checkbox, get disable while fetching the result, then check box checked or unchecked based on response.
bro i am appreciating ur help. but even its not working.
I'll make you an example, here.

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.