繁体   English   中英

为什么传递给备忘录的道具不存储值

[英]Why the props that are passed to memo are don't store the value

我正在尝试使用手动道具比较的 React 备忘录功能优化我的 React 列表渲染。 我生成了一个简单的“切换”按钮列表:

import React, { useState } from "react";
import "./styles.css";
import { Toggle } from "./Toggle";

export default function App() {
  const [list, setList] = useState({ a: true, b: true, c: true });
  const handleClick = x => {
    console.log(list);
    const currentValue = list[x];
    setList({ ...list, [x]: !currentValue });
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      {Object.keys(list).map(x => (
        <Toggle key={x} isChecked={list[x]} name={x} onChange={handleClick} />
      ))}
    </div>
  );
}

这是“切换”按钮:

import React from "react";

const areEqual = (prevProps, nextProps) => {
  return prevProps.isChecked === nextProps.isChecked;
};

const ToggleComponent = ({ isChecked, name, onChange }) => {
  return (
    <>
      <h1>{isChecked ? "This is true" : "This is false"}</h1>
      <button onClick={() => onChange(name)}>{name}</button>
    </>
  );
};

export const Toggle = React.memo(ToggleComponent, areEqual);

我的问题是列表 object 实际上没有存储预期值。 每次我点击按钮时都会得到相同的结果,默认一个{ a: true, b: true, c: true } (在handleClickconsole.log中可见),但如果我删除areEqual function,一切正常再次正确,列表 object 已按原样更新。

代码沙箱示例

编辑cool-sun-wq1f6

编辑:

我看到如果我将整个内容更改为一个数组并将每个按钮包装到一个 object 中,备忘录功能将按预期工作。

带数组的代码沙箱示例

编辑cool-sun-wq1f6

这是因为handleClick function 被创建并传递给了一个Toggle组件。 并且handleClick's闭包包含旧的list值,因此每当旧值更改时,它都不会更新。

最简单的解决方法是从 state 更新程序的第二个签名中受益:一个 function,它在参数中接受旧的 state 值。

因此,无论何时调用它,react 都会将旧的 state 值传递给它。

const handleClick = x => {
  setList(old => ({ ...old, [x]: !old[x] }));
};

您还需要记住handleClick memoize ,因为it is recreated at each render

const handleClick = React.useCallback(x => {
  setList(old => ({ ...old, [x]: !old[x] }));
}, [setList]);

这是工作代码和框

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM