【问题标题】:Automatic batching in React 18 is not working?React 18 中的自动批处理不起作用?
【发布时间】:2022-12-15 05:51:24
【问题描述】:

因此,我有一个受控输入组件和一个采用另一个状态变量的 div。这两个状态在单个回调函数中更新。为什么 input 中的值和下面 div 中的文本不同步?

`import React, {useState, useRef} from "react";

const Input =()=>{
    const [search, setSearch] = useState('jk');
    const [text, setText] = useState('');

 const onChange =(e)=>{
   setSearch(e.target.value) 
   setText(search)  
  }

return(
    <>
      <input type='text' value={search} onChange={onChange} />
      <div>{text}</div>
        </>
)
};

export default Input`

我知道关闭和陈旧状态,但 React 18 的自动批处理不是应该解决这个问题吗?

【问题讨论】:

  • 自动批处理是,在运行所有 setState 之后更新状态,然后最后一个一个地设置它们 .... 所以 search 更新的值尚不可用,并且在下一个渲染中可用,自动批处理与它 ..

标签: reactjs react-18


【解决方案1】:

React 状态更新是不可变的。当你setSearch(e.target.value)时,你是不是在组件的闭包中改变 search 变量。 search 变量将不会反映您的新值,直到随后的渲染。否则,我们都只是使用常规变量并根据需要改变它们,但 React 将无法知道它应该重新渲染。

只是为了更明确地说明这一点:

const [search, setSearch] = useState('jk');
const [text, setText] = useState('');

const onChange = (e) => {
  // the `search` variable above will not reflect this new value until the next render
  setSearch(e.target.value)

  // false (unless they typed "jk" again)
  search === e.target.value

  // you are still using the old search value from the last render when search was defined as "jk"
  setText(search)  
}

有两种解决方法。一种是简单地将它们设置为相同的值:

const newSearch = e.target.value
setSearch(newSearch)
setText(newSearch)

^ 我个人更喜欢这个例子中的那个,因为它很简单,应该只导致一次重新渲染,但另一种模式是使用useEffect,因为显示的文本是从搜索值派生的,或者换句话说,你想要更新文本作为搜索值更改的副作用。

const onChange = (e) => {
  setSearch(e.target.value)
}

// whenever search changes, update the text
useEffect(() => {
  setText(search)
}, [search])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    • 2019-09-27
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多