如何通过反应钩子点击按钮发送http请求?或者,就此而言,如何对按钮点击产生任何副作用?
到目前为止我所看到的是有一些“间接”的东西:
export default = () => {
const [sendRequest, setSendRequest] = useState(false);
useEffect(() => {
if(sendRequest){
//send the request
setSendRequest(false);
}
},
[sendRequest]);
return (
<input type="button" disabled={sendRequest} onClick={() => setSendRequest(true)}
);
}
这是正确的方式还是有其他模式?
export default () => {
const [isSending, setIsSending] = useState(false)
const sendRequest = useCallback(async () => {
// don't send again while we are sending
if (isSending) return
// update state
setIsSending(true)
// send the actual request
await API.sendRequest()
// once the request is sent, update state again
setIsSending(false)
}, [isSending]) // update the callback if the state changes
return (
<input type="button" disabled={isSending} onClick={sendRequest} />
)
}
这就是当你想要发送点击请求并在发送时禁用按钮时,它可以归结为什么
你不需要效果来发送按钮点击请求,而你需要的只是一个处理器方法,你可以使用useCallback
方法优化
const App = (props) => {
//define you app state here
const fetchRequest = useCallback(() => {
// Api request here
}, [add dependent variables here]);
return (
<input type="button" disabled={sendRequest} onClick={fetchRequest}
);
}
使用带有useEffect
的变量的跟踪请求不是正确的模式,因为您可以使用useEffect设置状态来调用api,但是由于某些其他更改而导致的额外渲染将导致请求进入循环
你可以像你一样在状态中定义布尔值,一旦你触发请求就把它设置为true
,当你收到响应时,将它设置回false
:
const [requestSent, setRequestSent] = useState(false);
const sendRequest = () => {
setRequestSent(true);
fetch().then(() => setRequestSent(false));
};
您可以像在问题中一样获取数据作为某些状态更改的效果,但您也可以像在单元组件中习惯的那样直接在单击处理程序中获取数据。
例
const { useState } = React;
function getData() {
return new Promise(resolve => setTimeout(() => resolve(Math.random()), 1000))
}
function App() {
const [data, setData] = useState(0)
function onClick() {
getData().then(setData)
}
return (
<div>
<button onClick={onClick}>Get data</button>
<div>{data}</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>