ReactJS |子组件中的道具为空,直到我刷新父组件

问题描述 投票:0回答:2

我有一个正在运行的应用程序,道具没有任何问题,除非我必须在将这些变量发送到子组件之前对其进行过滤。这是我的父组件:

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import ItemDetail from './ItemDetail';

const ItemDetailContainer = () => {
    const { itemId } = useParams();
    const [catData, setCatData] = useState([]);
    const [prodData, setProdData] = useState([]);

    const getData = () => {
        fetch('/data.json', {
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
            },
        })
            .then(function (response) {
                return response.json();
            })
            .then(function (myJson) {
                setProdData(myJson['products'].find((c) => c.id == itemId));
                setCatData(myJson['categories'].find((c) => c.catId == prodData.catId));
            });
    };
    useEffect(() => {
        getData();
    }, []);

    if (prodData === null || catData === null || prodData === undefined || catData === undefined) {
        return null;
    }

    return <ItemDetail prodInfo={prodData} catInfo={catData} />;
};

export default ItemDetailContainer;

当我在 ItemDetail 中收到这些道具时,我得到一个空白对象:

但是当我返回代码并点击 ItemDetailContainer(父组件)上的“保存”时,我从子组件的 props 中获取内容:

我尝试过使用带有或不带有依赖项、超时、间隔、从函数返回的 useEffect...不知道还能尝试什么。有线索吗?

顺便说一句,我只在控制台上显示其中一个道具。这就是为什么它们是相同的(不知道为什么它们总是出现两次)。

提前非常感谢!

javascript reactjs react-props
2个回答
0
投票

useState
将您的值保存到下一个渲染,因此当您调用
find(c.catId === prodData.catId)
时,您的
prodData.catId
仍然是旧的(因为 React 尚未重新渲染)。

解决方案非常简单,只是不要使用该状态值并使用从 json 中获得的值,有点像:

    .then(function (myJson) {
      const newProductData = myJson['products'].find((c) => c.id == itemId
      setProdData(newProductData);
      setCatData(myJson['categories'].find((c) => c.catId == newProductData.catId));
    });

另一个仅供参考:由于 React 的严格模式,你的日志会出现两次。它将在开发环境中运行您的钩子两次,以确保一切都按预期工作(如果不是,则显示警告)。您可以将其关闭,但不建议这样做。


0
投票

这可能对这件事有好处。

 .then(function (myJson) {
    const tmp_prodData = myJson['products'].find((c) => c.id == itemId)
    setProdData(tmp_prodData);
    setCatData(myJson['categories'].find((c) => c.catId == tmp_prodData.catId));
 });

...

useEffect(() => {
  return (<ItemDetail prodInfo={prodData} catInfo={catData} />)
}, [prodData, catData])
© www.soinside.com 2019 - 2024. All rights reserved.