从 API 获取数据后立即将数据从父组件传递到子组件时出现问题。 (仅限功能组件)

Posted

技术标签:

【中文标题】从 API 获取数据后立即将数据从父组件传递到子组件时出现问题。 (仅限功能组件)【英文标题】:Issues when passing data from parent to child component right after fetching data from API. (functional components only) 【发布时间】:2021-03-18 08:32:52 【问题描述】:

我需要将从 API 获取的数据传递给子功能组件。下面,您将看到我在未成功尝试中所遵循的步骤。

这是从随机 API 获取数据的 组件:

import React,  useState, useEffect  from 'react';
import SideMenu from '../Components/SideMenu';

export default function ProductsPage() 
  const [products, setProducts] = useState([]);

  useEffect(() => 
    fetchProducts();
  , []);

  const fetchProducts = async () => 
    const url = 'https://restcountries.eu/rest/v2/all';
    const data = await fetch(url);
    const items = await data.json();
    setProducts(items);
  ;

  return (
    <div>
      <SideMenu prods=products />;
    </div>
  );

这是 child 组件,应该从父组件接收道具。这无法更改:

import React,  useState, useEffect  from 'react';

export default function SideMenu(props) 
  const [products2, setProducts2] = useState([]);

  useEffect(() => 
    setProducts2(props.prods);
  , []);

  return (
    <div>
      console.log(products2)
    </div>
  );

我很难弄清楚为什么我没有在子组件中获得所需的数据。如果你能帮我解决这个问题,我将不胜感激。

P.S.:我不允许使用类组件,也不能更改子组件。

【问题讨论】:

【参考方案1】:

子组件在效果挂钩中执行setProducts2(props.prods);,在它安装后不久,在父组件的fetch 完成之前。此时,prods 将是父组件中的初始产品:空数组。

执行此操作的正确方法通常是从子组件中删除状态,并仅使用道具 - ,至少每次调用setProducts2 props.prods更改(使用依赖数组)。但是如果子组件不能改变,那两者都不可能。

但是,您可以在父组件中,仅在响应返回后有条件地渲染 SideMenu,确保传递给 SideMenu 的初始道具包含所有必要的数据:

  return (
    <div>
      products.length && <SideMenu prods=products />
    </div>
  );

【讨论】:

这样一个简单的解决方案,而且效果很好!太感谢了!欣赏! 非常感谢您花时间向我解释整个机制。祝你好运。【参考方案2】:

如果将其存储在父组件中,则子组件中不需要 useEffectuseState

import React,  useState, useEffect  from 'react';

export default function SideMenu(props) 
  return (
    <div>
      console.log(props.prods)
    </div>
  );

【讨论】:

他说子组件不能更改。,很遗憾。奇怪的要求。 除非是某种学校问题,否则我不确定我是否理解该要求。 实际上,他们只是将一个简单的解决方案复杂化,不允许我删除useEffectuseState。我无法展示完整的组件来更好地解释它,但无论如何谢谢。【参考方案3】:

最好的解决方案是在子组件中使用 useEffect 并在 props 更改时更新它。

import React,  useState, useEffect  from 'react';

export default function SideMenu(props) 
  const [products2, setProducts2] = useState([]);

  useEffect(() => 
    setProducts2(props.prods);
  , [props.prods]);

  return (
    <div>
      console.log(products2)
    </div>
  );

【讨论】:

以上是关于从 API 获取数据后立即将数据从父组件传递到子组件时出现问题。 (仅限功能组件)的主要内容,如果未能解决你的问题,请参考以下文章

如何在角度2中将数据从父构造函数传递到子组件

将数据从父模式传递到子模式 - Vue.js

如何将 Angular 5 中的点击数据从父组件传递到子组件?

如何从父级获取数据到子级?

Angular 2 单元测试数据从父组件传递到子组件

如果数据属性在 VueJs 中从父组件传递到子组件,则无法将其作为对象进行操作