当前位置: 首页 > 知识库问答 >
问题:

react.js - 子组件在父组件循环调用,子组件的数据是固定的,想做优化,这样做对吗?

长孙承嗣
2024-03-18

问题1 子组件是个select ,数据都是从api获取,每次都是固定的内容。
父组件中的列表需要大量调用这个子组件,每次这个组件都需要调用api获取数据,每次数据都是一样,这个地方是不是需要优化?

问题2 如果需要优化的话,从react官网找了一下,简单做了更改,理论上每次excuteCallBack 是同一个引用,但是debug的时候 useEffect每次被调用没法证明excuteCallBack 是不是同一个引用呢?

理解不足,希望解答一下。

import React, { useCallback, useEffect, useState } from "react";import { Team, User } from "@/type/user";import { Select } from "antd";import { getTeams } from "@/api";const { Option } = Select;interface Props {  record: User;}const CusSelect: React.FC<Props> = ({ record }) => {  const [teams, setTeams] = useState<Array<Team>>(); const excuteCallBack = useCallback(   () => {    return getTeams()   },   [] )   useEffect(() => {    console.log('excuteCallBack reference:',new Date(), excuteCallBack);    async function excute() {      try {        let rest = await excuteCallBack();        //debugger        setTeams(rest.data);      } catch (error) {        console.log(error);      }    }    excute();  }, [excuteCallBack]);  return (    <Select      className="w-4/5"      defaultValue={record.team_name}      disabled={record.role_name != "コーチ"}      onChange={(value) => {        alert(JSON.stringify(record) + value);      }}    >      {teams?.map((item) => (        <Option value={item.team_id} key={item.team_id}>          {item.team_name}        </Option>      ))}    </Select>  );};export default CusSelect;

共有1个答案

柯瀚海
2024-03-18

问题1:是的,如果子组件的数据是固定的,并且每次父组件循环调用时都重新从API获取这些数据,那么这确实是一个可以优化的地方。因为每次获取相同的数据是不必要的,这会导致性能浪费和可能的延迟。

问题2:你的优化思路是正确的,使用useCallback来确保excuteCallBack在依赖项不变的情况下保持引用稳定,从而避免不必要的useEffect调用。然而,要验证excuteCallBack是否真的是同一个引用,你不能仅仅依赖console.log的输出,因为每次useEffect运行时,它都会打印出当前的引用和当前的时间戳,这并不能证明引用是否改变。

要验证excuteCallBack的引用是否改变,你可以尝试在父组件中记录每次CusSelect组件渲染时传入的excuteCallBack引用,并在多次渲染之间比较这些引用。如果引用确实保持不变,那么你的优化就是有效的。

此外,为了进一步优化,你可以考虑将API调用移到父组件中,并将获取到的数据作为属性传递给子组件。这样,子组件就可以避免不必要的API调用,并且只在数据发生变化时重新渲染。

下面是一个示例代码,展示了如何将API调用移到父组件中,并将数据作为属性传递给子组件:

import React, { useState, useEffect } from "react";import { getTeams } from "@/api";import CusSelect from "./CusSelect";const ParentComponent = () => {  const [teams, setTeams] = useState([]);  useEffect(() => {    const fetchData = async () => {      try {        const rest = await getTeams();        setTeams(rest.data);      } catch (error) {        console.log(error);      }    };    fetchData();  }, []); // 确保只在组件挂载时运行一次  return (    <div>      {/* 假设你有一个列表需要渲染 */}      {list.map((record) => (        <CusSelect key={record.id} record={record} teams={teams} />      ))}    </div>  );};export default ParentComponent;

然后,在CusSelect组件中,你可以直接使用传入的teams属性,而不再需要调用API:

const CusSelect: React.FC<Props> = ({ record, teams }) => {  return (    <Select      className="w-4/5"      defaultValue={record.team_name}      disabled={record.role_name != "コーチ"}      onChange={(value) => {        alert(JSON.stringify(record) + value);      }}    >      {teams.map((item) => (        <Option value={item.team_id} key={item.team_id}>          {item.team_name}        </Option>      ))}    </Select>  );};

这样,你就可以避免在每次渲染CusSelect组件时都重新从API获取数据,从而提高性能。

 类似资料:
  • vue2 在子组件监听父组件的值value变化,对子组件监听父组件传来的value,之后做更新操作,会导致父组件的requestAnimationFrame的循环更新value值卡顿,这是什么问题? 子组件

  • 一般来讲vue父组件的数据发生变化会触发父组件渲染,如果父组件传入子组件的props数据发生变化会触发子组件渲染,如果 vue 中 父组件的props和子组件的数据同时发生变化,子组件会渲染2次吗? 如题

  • 我在用vue-cli支架做网页包 我的Vue组件结构/传家宝目前看起来如下: 应用程序 在应用程序级别,我需要一个vuejs组件方法,该方法可以将子组件的所有数据聚合到一个JSON对象中,然后发送到服务器。 有没有办法访问子组件的数据?具体来说,多层深? 如果没有,传递oberservable数据/参数的最佳实践是什么,这样当子组件修改它时,我就可以访问新的值?我试图避免组件之间的硬依赖关系,所以

  • 我有一个父组件[MainLayout],它有一个子组件[ListItems],并且有多个子组件[ListItem]。 谢谢你的回答!

  • 本文向大家介绍Vue父组件调用子组件事件方法,包括了Vue父组件调用子组件事件方法的使用技巧和注意事项,需要的朋友参考一下 Vue父组件向子组件传递事件/调用事件 不是传递数据(props)哦,适用于 Vue 2.0 方法一:子组件监听父组件发送的方法 方法二:父组件调用子组件方法 子组件: 父组件: 以上这篇Vue父组件调用子组件事件方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希

  • 我有一个在父组件中生成的事件,子组件必须对此作出反应。我知道在中不建议使用这种方法,我必须执行emit,这非常糟糕。所以我的代码是这个。 正如您所看到的,在无限滚动上被触发,事件被发送到子组件搜索。不仅仅是搜索,因为它是根,所以它正在向每个人广播。 什么是更好的方法。我知道我应该使用道具,但我不知道在这种情况下我该怎么做。