React Hook 状态到底是什么时候设置的?

When exactly do React Hook states get set?

我试图了解以下涉及 React Hook 状态的代码的执行顺序:

const App = () => {
  const [ searchedCountry, setSearchedCountry ] = useState(''); 
  const [ filteredArr, setFilteredArr ]  = useState([]); 
  const [ filteredLength, setFilteredLength ] = useState(0);

  //...

  const filterCountries = (event) => { 
    event.preventDefault();

    setFilteredArr(countries.filter(country => country.name.includes(searchedCountry)));  
    setFilteredLength(filteredArr.length); 
    console.log("filtered arr length", filtered.length);
  }

  //...
}

filterCountries 被触发时,setFilteredArr 将状态 filteredArr 设置为由查询过滤的数组。但是,filteredArr 到底是什么时候设置的?

filteredArr.length returns 0,意思是filteredArr还没有设置,即使调用了setFilteredArr

起初我以为通过执行setFilteredArr,组件重新渲染,导致执行跳过setFilteredArr之后的方法调用。这可以解释为什么 filteredArr.length0。但是,console.log 仍然被调用,意思是在组件重新渲染后,执行顺序实际上恢复了。

这是怎么回事? filteredArr 什么时候设置?

要记住的是:你所有的状态变量都是局部变量。它们仅在组件呈现的这个特定时间存在。所以在第一个渲染中,console.log("filtered arr length", filteredArr.length); 指的是第一个渲染中存在的数组。 filteredArr 永远不会被分配一个新数组(它不能,它是一个常量),除非你改变数组(你不应该),该数组的长度将始终为 0.

当您调用 setFilteredArr 时,这会指示重新渲染组件。 React 可能会同步进行渲染,或者它可能会等待尝试批量更改。当第二次渲染发生时,您调用 useState 并取回新值。这被分配给一个名为 filteredArr 的局部变量,但这是一个与我们在第一次渲染时使用的变量完全不同的变量。第一次渲染中的 console.log 语句将无法访问第二次渲染中的变量。但是第二个渲染器可以访问它,所以你第二次做的任何日志记录都会显示第二个数组。

setState 或 'setFilteredLength' 是一个异步操作。在你调用它之后,它会花一些时间来更新状态(因为它是异步的,它不会等待那个更新。它只会执行下一行)所以当它执行 console.log 时,值还没有已更改 -> 尚未