gpt4 book ai didi

reactjs - useMemo 钩子(Hook)不适用于 map 元素

转载 作者:行者123 更新时间:2023-12-04 12:19:07 26 4
gpt4 key购买 nike

我正在使用 useMemo 钩子(Hook)来渲染 map 项。我向 useMemo 钩子(Hook)添加了 items 参数,基于它会呈现的项更改。但是改变加载状态和元素改变,元素自定义组件渲染两次。我在使用 useMemo 钩子(Hook)时是否有任何错误,请纠正我。

Home:

import React, { useState, useEffect, useMemo } from "react";
import Item from "./Item";

const array = [1];
const newArray = [4];

const Home = () => {
const [items, setItems] = useState(array);
const [loading, setLoading] = useState(false);
const [dataChange, setDataChange] = useState(1);

const renderItems = (item, index) => {
return (
<div key={item}>
<Item id={item}></Item>
</div>
);
};
useEffect(() => {
if (dataChange === 2) {
setLoading(true);
setTimeout(() => {
setLoading(false);
setItems(newArray);
}, 3000);
}
}, [dataChange]);

const memoData = useMemo(() => {
return <div>{items.map(renderItems)}</div>;
}, [items]);

return (
<div style={{ display: "flex", flexDirection: "column" }}>
<input
onClick={() => {
setDataChange(2);
}}
style={{ height: 40, width: 100, margin: 20 }}
type="button"
value="ChangeItem"
></input>
<div>{loading ? <label>{"Loading"}</label> : <div>{memoData}</div>}</div>
</div>
);
};
export default React.memo(Home);

Item:

import React,{useEffect} from "react";
const Item = (props) => {
console.log("props", props);
useEffect(() => {
// call api with props.id
}, [props]);
return <div>Hello world {props.id}</div>;
};
export default React.memo(Item);
结果:
第一次 : props {id: 1}点击后: props {id: 1} props {id: 4}

最佳答案

上面的代码中有一些不正确的地方。

  • key应该在数组迭代中传递给父元素 - 在您的情况下是 renderItems应该通过 keydiv元素
  • 您正在关闭 loading更新前的状态 items数组,切换两个 setState尽管 setState 表达式将在大多数情况下解决您的情况是一个异步函数,这不能保证
  • 如果常量或函数与组件的状态没有紧密耦合,最好将其提取到组件外部,就像 renderItems 的情况一样。

  • 这就是执行多一个 console.log 的原因
    enter image description here
  • 还应该记住,内存需要时间,您希望尽可能保持高效,因此您可以完全跳过 useMemoReact.memo处理数组的组件,因为它保持在状态中,如果状态保持不变,它的引用在重新渲染时不会改变
  •     const array = [1];
    const newArray = [4];

    const Home = () => {
    const [items, setItems] = useState(array);
    const [loading, setLoading] = useState(false);
    const [dataChange, setDataChange] = useState(1);

    useEffect(() => {
    if (dataChange === 2) {
    setLoading(true);
    setTimeout(() => {
    setItems(newArray);
    setLoading(false);
    }, 3000);
    }
    }, [dataChange]);

    return (
    <div style={{ display: "flex", flexDirection: "column" }}>
    <input
    onClick={() => {
    setDataChange(2);
    }}
    style={{ height: 40, width: 100, margin: 20 }}
    type="button"
    value="ChangeItem"
    ></input>
    <div>
    {loading ? <label>{"Loading"}</label> : <ItemsMemo items={items} />}
    </div>
    </div>
    );
    };

    const renderItems = (item) => {
    return (
    <span key={item} id={item}>
    {item}
    </span>
    );
    };

    const Items = ({ items }) => {
    console.log({ props: items[0] });

    return (
    <div>
    Hello world <span>{items.map(renderItems)}</span>
    </div>
    );
    };

    const ItemsMemo = React.memo(Items);
    更新
    This codesandbox显示 useMemo仅在 items 时被调用值按预期变化。
    enter image description here

    关于reactjs - useMemo 钩子(Hook)不适用于 map 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69313589/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com