sky*_*ine 6 reactjs react-hooks react-usememo
我正在使用 useMemo 挂钩来渲染地图项目。我向 useMemo 挂钩添加了 items 参数,根据项目更改它将呈现。但是改变加载状态和items发生变化,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);
Run Code Online (Sandbox Code Playgroud)
结果: 第一次:
props {id: 1}
点击后:
props {id: 1}
props {id: 4}
上面的代码中有一些不正确的地方。
key应该在数组迭代中传递给父元素 - 在您的情况下应该将renderItems传递key给div元素loading您在更新数组之前关闭状态items,切换两个setState表达式将在大多数情况下解决您的情况,尽管setState这是一个异步函数并且不能保证renderItemsuseMemo改变React.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);
Run Code Online (Sandbox Code Playgroud)
更新
此codesandbox显示useMemo仅当items值按预期发生变化时才会被调用。
| 归档时间: |
|
| 查看次数: |
5463 次 |
| 最近记录: |