React 功能组件状态更改不会触发 child 组件到 re-read 其道具

React functional component state change does not trigger child component to re-read its props

我有这个 React 功能组件。我们知道,从 v16.8 开始,功能组件有一种 "state"。它使用 useEffect 到 "setState" 来声明变量 products。 然后我将 product 作为 child 组件 *ProductGrid 的属性。 我将 ProductOfCategory 作为 parent 组件,它将从 URL 获取数据并将结果设置为状态变量 "products"。我希望 child 组件 ProductGrid 能够读取该数据(更改),所以我让它看起来像这样。

Parent:

    export default function ProductOfCategory() {

    let { categoryId } = useParams();
    const [products, setProducts] = useState([]);

    useEffect(() => {
        fetch('/products/cat/' + categoryId)
            .then(response => response.json())
            .then(data => {
                setProducts(data);
                console.log("Fetch me: ", data);
            });
    }, [categoryId]);


    return (
        <div>
            <h3>ID: {categoryId}</h3>
            <ProductGrid products={products} />
        </div>
    );
}

Child:

class ProductGrid extends Component {

    constructor(props) {
        super(props);
        this.state = { products: this.props.products};
        console.log("ProductGrid.props.products: ", this.props);
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("Grid did update, products: ", this.state.products);
    }
}

结果: 当 parent 中的数据发生变化时,我可以看到(在控制台中)child 组件 (ProductGrid) 也是 re-rendered,但它的 prop 变量 "products" 不是。它始终是一个空数组。这是什么原因呢?这是否意味着功能组件的状态不同于遗留状态? 有办法克服这个问题吗?

非常感谢。

你的问题在线

console.log("Grid did update, products: ", this.state.products);

此处您正在记录子组件的状态。当您构建子组件时,您将 prop.products 复制到 state.products。然后,当 prop.product 发生变化时,您不会更新状态以反映该变化,而是继续打印传递给组件的 products 的初始值。

此处的解决方案是使用 this.props.products 而不是 this.state.products