我是react 的新手,我正在阅读这篇article,以了解如何react 呈现机制.我遇到了这个例子:
function App() {
const [body, setBody] = React.useState()
const [status, setStatus] = React.useState('idle')
const fetchConfig = {
method: 'POST',
body,
headers: {'content-type': 'application/json'},
}
const makeFetchRequest = () => (body ? fetch('/post', fetchConfig) : null)
React.useEffect(() => {
const promise = makeFetchRequest()
// if no promise was returned, then we didn't make a request
// so we'll exit early
if (!promise) return
setStatus('pending')
promise.then(
() => setStatus('fulfilled'),
() => setStatus('rejected'),
)
}, [makeFetchRequest])
function handleSubmit(event) {
event.preventDefault()
// get form input values
setBody(formInputValues)
}
return (
<form onSubmit={handleSubmit}>
{/* form inputs and other neat stuff... */}
</form>
)
}
作者表示,这App
个组件将导致无限渲染:
猜猜会发生什么事.如果你猜"离家出走 副作用循环"你说得对!原因是因为React.useEffect 将触发对给定效果回调的调用 依赖项数组的元素会更改.我们唯一的依靠就是 在组件中创建了MakeFetchRequest和MakeFetchRequest. 这意味着每一次渲染都是新的.
我想用一个更简单的例子来模拟这种行为:
import { useEffect, useState } from 'react';
const App = () => {
const [state, setState] = useState(0);
const fn = () => {
setState(1);
};
useEffect(() => {
console.log('side effect');
fn();
}, [fn]);
};
export default App;
我期待无限的渲染,因为在组件重新渲染之后,调用fn
会导致state
更改,这会导致重新渲染,这会导致新的fn
实例,这应该会导致重新渲染,因为我们依赖于它,这会继续进行,但这不是正在发生的事情.useEffect
钩子似乎只执行两次.但在作者的例子中,它会导致无限循环.我不确定我在这里理解错了什么
Updated个
我想我现在明白了.
Author's case个
当useEffect
钩子执行时.它将status
设置为挂起,并且在异步操作之后,status
被再次设置为"已完成"或"被拒绝",因此App
组件被再次执行,其中makeFetchRequest
的新实例导致组件重新呈现,依此类推.
My case个
useEffect
钩子第一次呈现,调用fn
并更改state
,这会导致重新呈现和一个新的fn
实例,但这里的REACT识别出实现保持不变,因此它不会重新呈现组件