使用React Hook,尝试使用forEach提取多个数据

Cha*_*lle 5 state reactjs react-hooks

我正在尝试从Figma API中获取数据,但不幸的是,我无法在一个调用中做到这一点。我首先需要获取一个团队中所有项目的列表,然后为每个项目获取文件列表。

这是我要做的代码:

  const [projects, setProjects] = useState([]);
  const [files, setFiles] = useState([]);

  useEffect(() => {
    const fetchProjects = async () => {
      const result = await axios(
        `https://api.figma.com/v1/teams/${teamId}/projects`, {
          headers: { 'Authorization': `Bearer ${token}` }
        });
      setProjects(result.data.projects);
    };

    fetchProjects();
  }, []);

  useEffect(() => {
    projects.forEach(project => {
      const fetchFiles = async () => {
        const result = await axios(
          `https://api.figma.com/v1/projects/${project.id}/files`, {
            headers: { 'Authorization': `Bearer ${token}` }
          });

        setFiles([ ...files, {
          projectName: project.name,
          files: result.data.files
        }])
      };

      fetchFiles();
    })
  }, [projects]);
Run Code Online (Sandbox Code Playgroud)

我明确地仅将其projects作为对第二个useEffect的依赖项,否则它将创建许多不同的渲染,并且我只想在项目列表中循环。

在我的Figma团队中,我有4个项目。每个都有1到5个文件。我希望状态文件具有4个对象,这些对象包含项目的名称及其包含的文件列表。

我今天遇到的问题是,首先,我有一些来自React的警告,我需要放置其他依赖项,其次,我的文件状态仅填充了最新的项目,而没有全部填充这四个项目。

Shu*_*tri 3

就状态而言,您会遇到此问题,因为您尝试根据闭包变量更新循环中的状态。相反,您可以使用回调模式来更新状态。这也不会警告您将文件作为依赖项添加到useEffect.

您也可以将 fetchFiles 函数移出循环之外。

您还可以选择添加 setFiles 方法作为依赖项或禁用警告,因为它不会影响您的代码。setFiles函数不会在代码范围内改变

const [projects, setProjects] = useState([]);
  const [files, setFiles] = useState([]);

  useEffect(() => {
    const fetchProjects = async () => {
      const result = await axios(
        `https://api.figma.com/v1/teams/${teamId}/projects`, {
          headers: { 'Authorization': `Bearer ${token}` }
        });
      setProjects(result.data.projects);
    };

    fetchProjects();
  }, []);

  useEffect(() => {
    const fetchFiles = async (id, name) => {
        const result = await axios(
          `https://api.figma.com/v1/projects/${id}/files`, {
            headers: { 'Authorization': `Bearer ${token}` }
          });

        setFiles(prevFiles => ([ ...prevFiles, {
          projectName: name,
          files: result.data.files
        }]))
      };
    projects.forEach(project => {
      fetchFiles(project.id, project.name);
    })
  }, [projects]);
Run Code Online (Sandbox Code Playgroud)