首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何减少“useEffect`”挂钩以提高性能

如何减少“useEffect`”挂钩以提高性能
EN

Code Review用户
提问于 2023-01-12 04:56:09
回答 1查看 65关注 0票数 0

我发明了一台tab手风琴。目前它工作得很好。它应:

  1. 打开和关闭点击(洗牌)
  2. 单击选项卡时,如果已打开其他选项卡,则应关闭其他选项卡。

为此,我使用了2个userEffect钩子和一个函数来处理单击事件。它也是从上下文中利用provider。我对我考虑表演的方法有点困惑。

如果我错了,请有人复习一下代码,并给出建议。

下面是我的代码和演示:

代码语言:javascript
复制
  import React, {
  createContext,
  ReactNode,
  useContext,
  useEffect,
  useState
} from "react";
import "./styles.css";

export interface ContextProps {
  isExpand: number | null;
  childHandler: (v: number) => void;
}

export const initialContextProps: ContextProps = {
  isExpand: null,
  childHandler(v: number) {}
};

export const parentContext = createContext<ContextProps>(initialContextProps);
const { Provider } = parentContext;

function Children({ label, si }: { label: string; si: number }): JSX.Element {
  const { isExpand, childHandler } = useContext(parentContext);
  const [classProps, setClassProps] = useState(false);
  useEffect(
    function () {
      if (si === isExpand) {
        setClassProps(true);
      }
    },
    [setClassProps, si, isExpand]
  );

  useEffect(
    function () {
      if (si !== isExpand) {
        setClassProps(false);
      }
    },
    [setClassProps, si, isExpand]
  );

  function setClass(index: number) {
    setClassProps((prev) => !prev);
    childHandler(index);
  }

  return (
    <li onClick={() => setClass(si)} className={classProps ? "expand" : ""}>
      {label} :: {si} || {isExpand} -- {classProps}
      {classProps && <div>Content</div>}
    </li>
  );
}

function Parent({ children }: { children: ReactNode }): JSX.Element {
  const [isExpand, setIsExpand] = useState<number | null>(0);
  function childHandler(si: number) {
    setIsExpand(si);
  }
  return (
    <Provider value={{ isExpand, childHandler }}>
      <ul>{children} </ul>
    </Provider>
  );
}

export default function App() {
  return (
    <div className="App">
      <Parent>
        <Children key={1} label="Title-1" si={0} />
        <Children key={2} label="Title-2" si={1} />
        <Children key={3} label="Title-3" si={2} />
        <Children key={4} label="Title-4" si={3} />
        <Children key={5} label="Title-5" si={4} />
      </Parent>
    </div>
  );
}

现场演示

EN

回答 1

Code Review用户

发布于 2023-01-13 10:08:32

做的很好!然而,可以做一些改进:

关于编码约定的注释:

  • 请正确命名您的变量、函数、参数,以便其他人更容易查看您的代码。例如,siindex引用相同的东西,您应该在整个工作过程中保持命名的一致性。另一个例子是,ParentChildrenchildHandler听起来令人困惑,请将它们重命名为您正在进行的实际操作,如AccordionAccodionItemonOpen等。
  • 您可以将您的片段上传到github,这样评审人员就可以轻松地瞄准特定的行并指出确切的问题。

关于代码的

问题:

基本上,你的代码对你想要的东西来说是过分的。

  • 只在不经常更改的事情上使用反应语境,因为

当提供者的值支柱发生变化时,所有提供者的后代消费者都会重新呈现。

  • 您在每个子节点下定义了一个布尔状态,如果您已经在使用上下文,这是不必要的。expand状态可以由si === isExpand直接确定。
  • 两个useEffect回调具有完全相同的依赖关系,您可以将它们合并为一个,但同样,您不需要它们。

更好的解决方案:

考虑一下组件的数据结构。它可以是一个包含多个对象的数组,每个对象都具有属性idlabelisOpen。使其成为您的状态,并使用.map来呈现它们。通过这种方式,将传递到组件中的道具进行比较,如果道具保持不变,则跳过重新呈现,这样就更具有表现力。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/282530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档