【发布时间】:2021-10-05 20:12:20
【问题描述】:
我正在使用 useMemo 钩子来渲染地图项。我将 items 参数添加到 useMemo 钩子,基于项目更改它将呈现。但是改变加载状态和项目改变,Item 自定义组件渲染两次。我在使用 useMemo 钩子上有什么错误吗,请纠正我。
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}
【问题讨论】:
-
你可以创建一个沙盒吗?
-
不用useMemo也可以试试。
-
@karagoz 我得到了相同的结果,使用 useMemo 我想限制我的渲染元素。不幸的是,Item 组件渲染了两次
-
@问我不知道怎么加沙箱
-
另一种改进 useMemo 的方法是使用 JSON.stringify(items) 作为触发器。即使引用发生变化,这看起来也一样,只要内容相同,它就不会再次运行。所以基本上 useMemo(() => {}, [JSON.stringify(items)]);
标签: reactjs react-hooks react-usememo