Компонент React, который принимает переменную состояния в качестве параметра, который не отображается при обновлении - PullRequest
1 голос
/ 16 июня 2020

У меня есть компонент React, который выполняет вызов AJAX, устанавливает переменную состояния и затем передает эту переменную состояния в компонент.

Главный компонент:

export default function MyView({ assetId }) {
   const [asset, setAsset] = useState();
   const [beanstalk, setBeanstalk] = useState();
   const [loading, setLoading] = useState(true);

   useEffect(() => {
      loadAsset();
   }, []);

   const loadAsset = async () => {
        const _asset = await findAssetById(assetId);
        setLoading(false);
        if(_asset) {
            setAsset(_asset);
            await loadBeanstalk(_asset.id);
        }
    };

    const loadBeanstalk = async (assetId) => {
        const _beanstalk = await getBeanstalkFromDB(assetId);
        setBeanstalk(_beanstalk);
    };

   return (
      { loading ? (
         <div>Loading...</div>
      ) : (
         <h3>{asset.name}</h3>
         <ChildComponent beanstalk={beanstalk} />
      )}
   )
}

Дочерний компонент:

export default function ChildComponent({ beanstalk }) {
   const [loadbalancer, setLoadbalancer] = useState([]);
   const [loading, setLoading] = useState(true);

   useEffect(() => {
      console.log("Beanstalk will print as undefined here:");
      console.log(beanstalk);
      getLoadbalancer();
   }, []);

   const getLoadbalancer = async () => {
      if(beanstalk) {
         const _loadbalancer = await getLoadbalancer(beanstalk);
         setLoading(false);
         setLoadbalancer(_loadbalancer);
      }
   }

   return (
      { loading ? (
         <div>Loading...</div>
      ) : (
         <h3>{loadbalancer.name}</h3>
      )}
   )
}

Насколько я понимаю, основной компонент отображает при изменении состояния, поэтому, когда я вызываю setBeanstalk(_beanstalk), он должен повторно визуализироваться с установленной переменной состояния beanstalk ... так почему же ChildComponent всегда отображает Beanstalk как null, когда я знаю, что он возвращается из базы данных? Я знаю, что это как-то связано с порядком рендеринга.

1 Ответ

1 голос
/ 16 июня 2020

Так что проблема, похоже, в порядке операций. Вы можете попробовать сделать одно из следующего:

Переместите вызов setLoading(false) в loadBeanstalk(), чтобы ваш ChildComponent отображался только после того, как вы полностью загрузили материал.

const loadAsset = async () => {
    const _asset = await findAssetById(assetId);
    if(_asset) {
        setAsset(_asset);
        await loadBeanstalk(_asset.id);
    } else {
        setLoading(false);
    }
};

const loadBeanstalk = async (assetId) => {
    const _beanstalk = await getBeanstalkFromDB(assetId);
    setBeanstalk(_beanstalk);
    setLoading(false);
};

Присоедините beanstalk к useEffect крючку в ChildComponent.

useEffect(() => {
  console.log("Beanstalk will print as undefined here:");
  console.log(beanstalk);
  getLoadbalancer();
}, [ beanstalk ]);
...