问题描述
我想在更改复选框输入时调用 post API? 现在我正在以下面的模式执行此操作,但是在组件重新呈现此 API 函数时被调用?请问该怎么办?
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> )
解决方法
只需删除第二个 useEffect
并将您的 API 调用放入 onChange
函数中,如下所示:
为了获得更好的用户体验并避免不必要的调用,您应该在用户单击获取结果时禁用的复选框时添加加载状态,然后根据响应选中或取消选中。
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(),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>