为什么即使值不变,setState 也会重新渲染组件

3

React文档声称,如果您将State Hook更新为与当前状态相同的值,则React将放弃渲染子元素或触发效果。

然而,在该示例中似乎并非如此:

function Child() {
  useEffect(() => console.log("Re-render Child"));
  return (<div>Child</div>);
}

export default function App() {
  function Counter({ initialCount }) {

    const [state, setState] = useState({value: initialCount });

    useEffect(() => console.log("Re-render"));

    return (
      <>
        Count: {state.value}
        <br />
        <br />
        <button onClick={() => {
          state.value += 1;
          setState(state);
        }}>+1</button>
        <Child></Child>
      </>
    );
  }

  return (
    <div>
      <Counter initialCount={1} />
    </div>
  );
}

点击按钮只会更改内部属性 value,但对象仍然相同,那么为什么React会触发重新渲染(包括子元素的重新渲染和触发console.log效果)?
这里有一个沙盒来测试: https://codesandbox.io/embed/react-hooks-counter-example-wrr2p

你正在错误地使用它。请使用 useEffect(() => console.log("重新渲染"), []); - Praveen Kumar Purushothaman
1
请注意,React 在放弃之前可能仍需要重新渲染该特定组件。文档中的下一行。 - Vaibhav Vishal
@VaibhavVishal 当然可以,但它也会重新渲染子组件。我已经测试过了。 - Flavien
1
@PraveenKumarPurushothaman 不,我想在每次渲染时触发效果,所以不应该提供[]参数。 - Flavien
2个回答

1
问题在于您正在使用旧的 React alpha 版本 16.7.0-alpha.0(我认为回退特性尚未实现)。只需更新到最新版本,问题就解决了:更新沙盒

好的发现!我知道我漏掉了一些显而易见的东西。 - Flavien

1

使用这段代码,首先你需要导入useState,然后你需要指定值将被存储在哪里:state+1。

import React, { useState } from 'react';
`

    setState({value:state+1});

那不是回答问题。 - Flavien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接