如何在道具更改期间让组件重新渲染
how to let component rerender during props change
我想在 PRODUCTS
改变时(点击按钮时)实现效果,列表也会改变,第一个类别改变为“哈哈”。
整个objective就是让组件在props改变的时候重新渲染。但似乎它不起作用。下面是代码。
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
const FilterableProductTable = (props) =>{
return (
<ul>
{props.products.map((product) =>
(<li>{product.category}</li>)
)}
</ul>
);
}
const PRODUCTS = [
{ category: 'Sporting Goods', price: '.99', stocked: true, name: 'Football' },
{ category: 'Sporting Goods', price: '.99', stocked: true, name: 'Baseball' },
{ category: 'Sporting Goods', price: '.99', stocked: false, name: 'Basketball' },
{ category: 'Electronics', price: '.99', stocked: true, name: 'iPod Touch' },
{ category: 'Electronics', price: '9.99', stocked: false, name: 'iPhone 5' },
{ category: 'Electronics', price: '9.99', stocked: true, name: 'Nexus 7' }
];
const Home = () => {
const [productData, changeProduct] = useState(PRODUCTS);
const handleClick = () => {
PRODUCTS[0].category = 'haha';
changeProduct(PRODUCTS);
console.log(PRODUCTS);
};
return (
<>
<button onClick={handleClick}>haha</button>
<FilterableProductTable products={productData} />
</>
);
};
export default Home;
您可以在这里尝试:
如何让 FilterableProductTable
在 props 变化期间重新渲染?
当您在函数组件中设置状态时,React 会在新旧状态之间进行 ===
。如果它们相同,则 React 会跳过渲染。由于您正在改变状态,因此前后是相同的数组,并且跳过了渲染。
解决方法是让您的状态保持不变。不要修改旧数组,而是创建一个新数组:
const handleClick = () => {
changeProducts(prev => {
const next = [...prev];
next[0] = {
...next[0],
category: 'haha';
}
return next;
});
}
当更改数组中的 属性 时,React 不会将其视为更改,您可以使用扩展运算符克隆数组并设置新数组:
changeProduct([...PRODUCTS])
useState 将触发 re-render,仅当其当前值不同于当前状态时。它将进行 Object.is
或 ===
比较。在这里,您设置了与 defaultState 中相同的引用 PRODUCTS
,传递给 changeProduct
的值也具有与 PRODUCTS
相同的引用,这不会触发 re-render.
引用自 React DOCS
If your update function returns the exact same value as the current state, the subsequent rerender will be skipped completely.
const handleClick = () => {
const res = productData.map((prod,index) => index === 0 ? {...prod,category:"haha"} : prod)
changeProduct(res);
console.log(res);
};
map
每次都会创建一个新数组。
我想在 PRODUCTS
改变时(点击按钮时)实现效果,列表也会改变,第一个类别改变为“哈哈”。
整个objective就是让组件在props改变的时候重新渲染。但似乎它不起作用。下面是代码。
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
const FilterableProductTable = (props) =>{
return (
<ul>
{props.products.map((product) =>
(<li>{product.category}</li>)
)}
</ul>
);
}
const PRODUCTS = [
{ category: 'Sporting Goods', price: '.99', stocked: true, name: 'Football' },
{ category: 'Sporting Goods', price: '.99', stocked: true, name: 'Baseball' },
{ category: 'Sporting Goods', price: '.99', stocked: false, name: 'Basketball' },
{ category: 'Electronics', price: '.99', stocked: true, name: 'iPod Touch' },
{ category: 'Electronics', price: '9.99', stocked: false, name: 'iPhone 5' },
{ category: 'Electronics', price: '9.99', stocked: true, name: 'Nexus 7' }
];
const Home = () => {
const [productData, changeProduct] = useState(PRODUCTS);
const handleClick = () => {
PRODUCTS[0].category = 'haha';
changeProduct(PRODUCTS);
console.log(PRODUCTS);
};
return (
<>
<button onClick={handleClick}>haha</button>
<FilterableProductTable products={productData} />
</>
);
};
export default Home;
您可以在这里尝试:
如何让 FilterableProductTable
在 props 变化期间重新渲染?
当您在函数组件中设置状态时,React 会在新旧状态之间进行 ===
。如果它们相同,则 React 会跳过渲染。由于您正在改变状态,因此前后是相同的数组,并且跳过了渲染。
解决方法是让您的状态保持不变。不要修改旧数组,而是创建一个新数组:
const handleClick = () => {
changeProducts(prev => {
const next = [...prev];
next[0] = {
...next[0],
category: 'haha';
}
return next;
});
}
当更改数组中的 属性 时,React 不会将其视为更改,您可以使用扩展运算符克隆数组并设置新数组:
changeProduct([...PRODUCTS])
useState 将触发 re-render,仅当其当前值不同于当前状态时。它将进行 Object.is
或 ===
比较。在这里,您设置了与 defaultState 中相同的引用 PRODUCTS
,传递给 changeProduct
的值也具有与 PRODUCTS
相同的引用,这不会触发 re-render.
引用自 React DOCS
If your update function returns the exact same value as the current state, the subsequent rerender will be skipped completely.
const handleClick = () => {
const res = productData.map((prod,index) => index === 0 ? {...prod,category:"haha"} : prod)
changeProduct(res);
console.log(res);
};
map
每次都会创建一个新数组。