为什么我需要在函数中使用数组解构来重新呈现组件?

时间:2019-08-15 09:28:53

标签: reactjs react-hooks

在setBit函数中,我使用数组解构,并且更新了位并重新渲染了组件

<ul class="dropdown-menu">
 @foreach($menuItem->children as $subMenuItem)
  @if( ! $subMenuItem->status == 0 )
   <li class="nav-item"><a class="nav-link" href="{{ $subMenuItem->url }}">{{ $subMenuItem->title }}</a>
    @if( ! $subMenuItem->children->isEmpty() )
     <ul class="dropdown-menu">
      @foreach($subMenuItem->children as $childItem)
       @if( ! $childItem->status == 0 )
        <li class="nav-item"><a class="nav-link" href="{{ $childItem->url }}">{{ $childItem->title }}</a></li>
       @endif
      @endforeach
     </ul>
    @endif
   </li>
  @endif
 @endforeach
</ul>

但是当我返回prevState却没有那样的数组破坏

function App() {
  const [bits, setBit] = useState([0, 0, 0, 0, 0]);

  const changeBit = index => {

    setBit(prevState => {
      prevState[index] = 1;

      return ([...prevState])
    });
  };

  useEffect(() => console.log(bits));

  return (
    <div className="container">
      <div className="app">
        <ul>
          {bits.map((bit, index) => {
            return <li onClick={() => changeBit(index)}>{bit}</li>;
          })}
        </ul>
      </div>
    </div>
  );
}

这些位已更新,但该组件不会重新设置。

prevState和[... prevState]有什么区别?

Here is the link to codesandbox

2 个答案:

答案 0 :(得分:4)

这是因为您要返回相同的对象(到React)以更新状态(即prevState)-您已对该对象进行了突变-这不会导致重新渲染。如果对数组[... prevState]进行解构,则这是一个新对象,并导致重新渲染。

答案 1 :(得分:2)

使用javascript

let stringA = ‘some string’
let stringB = ‘some string’

stringA === stringB将返回true,因为stringA和stringB具有相同的值并引用相同的原语。

对象

不同
let stringA = new String(‘abc’)
let stringB = new String(‘abc’)

现在stringA === stringB将返回false,因为尽管值相等,但是在内存中创建了两个不同的对象,因此它们都引用了两个不同的对象,因此该比较在引用比较中失败了。

在您的情况下,prevState不等于[...prevState],因为它会在内存中创建一个新对象,并且根据React功能,它会将此状态视为一个新状态,随后会导致组件重新呈现