Реакция изменения состояния функционального компонента не запускает дочерний компонент для повторного чтения его свойств - PullRequest
0 голосов
/ 21 октября 2019

У меня есть этот функциональный компонент React. Мы знаем, что начиная с версии 16.8, функциональный компонент имеет своего рода «состояние». Он использует useEffect для "setState" для определения состояния переменной products . Затем я передаю product как реквизит для дочернего компонента * ProductGrid ". У меня есть ProductOfCategory в качестве родительского компонента, он будет извлекать данные из URL и устанавливать результат в переменную состояния" products ". Я хочу, чтобы дочерний элементкомпонент ProductGrid для возможности считывания этих данных (изменения), поэтому я сделал так, чтобы он выглядел следующим образом.

Родитель:

    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>
    );
}

Дочерний элемент:

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);
    }
}

Результат: Когда данные в родительском изменяются, я вижу (в консоли), что дочерний компонент (ProductGrid) также рендерится повторно, но его переменная пропа "products" - это НЕ. Это всегда пустой массив. В чем причинаэто? Означает ли это, что состояние функционального компонента отличается от унаследованного состояния? Есть ли способ преодолеть это?

Большое спасибо.

1 Ответ

1 голос
/ 21 октября 2019

Ваша проблема в линии

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

Здесь вы регистрируете состояние дочернего компонента. При создании дочернего компонента вы копируете prop.products в state.products. Затем, когда prop.product изменяется, вы не обновляете состояние, чтобы отразить это изменение, вы продолжаете печатать начальное значение products, которое было передано компоненту.

Решением здесь будет использование this.props.products вместо this.state.products.

...