理解React中的PrevState



我是React的新手,这可能是一个愚蠢的怀疑。但我没能找到答案。在React中使用state时,为了保持显示的更新,我们使用PrevState。例如:

const [state, setState] = useState(0);
setState(prevState => prevState +1);

据我所知,prevState通过1更新状态,并使UI与状态值保持最新。

但是,prevState是如何分配上一个状态的值的。这不就是箭头函数的参数名称吗?那么,这个名称是如何被假定为以前的状态值的呢?在forEach循环中,参数表示列表中的一个元素。但是在这里,参数PrevState是如何赋值的?

在内部,React为给定的组件实例保留一个所有状态的数组。例如,如果你有

const comp = () => {
const [state, setState] = useState(0);
const clickHandler = () => setState(prevState => prevState +1);
return <button onClick={clickHandler}>click</button>
};

然后,因为组件只有一个状态,所以在挂载时,React将有一个内部存储的一个项目的数组:

[0]

当调用useState时,React当前在其内部数组中为该状态所具有的值将被返回。因此,在上面的例子中,当你点击时,状态设置器会告诉React将其内部状态更新为:

[1]

之后,组件由于状态变化而重新渲染,因此重新渲染的useState返回的状态值为1。

当您使用状态设置器的回调形式时,例如

setState(prevState => prevState +1);

回调的参数直接来自React的内部。这有时比依赖外部状态标识符中的值更可靠,因为如果您之前设置了相同的状态而不等待重新呈现,则外部状态值将过期-例如,请注意以下内容如何使状态每次单击仅增加1,而不是增加2。

const App = () => {
const [count, setCount] = React.useState(0);
const clickHandler = () => {
setCount(count + 1);
setCount(count + 1);
};
return (
<div>
{count}
<button onClick={clickHandler}>click</button>
</div>
);
};
ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

相反,如果你使用回调版本,只要你调用第一个状态设置器,React的内部状态就会被更新——然后第二次调用状态设置器时,传递的参数将是React在状态中的最新更新值:

const App = () => {
const [count, setCount] = React.useState(0);
const clickHandler = () => {
setCount(count => count + 1);
setCount(count => count + 1);
};
return (
<div>
{count}
<button onClick={clickHandler}>click</button>
</div>
);
};
ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

只有当您有可能出现过时的闭包时,才需要回调方法。如果状态中的值没有过时的机会,那么就不需要回调,只需执行

setCount(count + 1);

会很好用的。

prevState如何分配上一个状态的值。这不就是箭头函数的参数名称吗?那么,这个名称是如何被假定为以前的状态值的呢?

prevState正如您所说的,只是函数的参数的名称。我们从名称prevState中没有获得任何其他东西,除了理解prevState将是组件状态的该部分最终更新后状态的值之外,这就是为什么它被称为以前状态的原因。

IMO,在回调中引用状态时,使用oldState而不是prevState是更好的术语,但实际上是oldState === state

证明oldState==statesetState

请记住,您可以只使用一个新的状态值而不是回调来调用setState。因此,以下内容将相当于您当前拥有的内容:

setState(state + 1);

如果我们假设setState的上述使用是将1添加到当前状态的正确方式(是的,它是正确的(,那么我们可以安全地假设,在使用setState时,如下所示:

setState(oldState => oldState +1);

CCD_ 16和CCD_。

由于我们不能在setState回调中使用名称state,我们可以创建一个名为currentState的别名,现在我们有了:

setState(currentState => currentState +1);

因此,oldState==state

QED。

最新更新