【问题标题】:react memo is not getting props反应备忘录没有得到道具
【发布时间】:2020-09-28 05:30:54
【问题描述】:

React memo 没有捕获 prevPropsnextProps 的道具,并且组件渲染良好。反应文档说

  • 如果您的函数组件在给定相同的 props 的情况下呈现相同的结果,您可以将其包装在对 React.memo 的调用中以提高性能。

我的问题是使用 react memo 停止两次渲染,但 memo 似乎无法正常工作,并且组件使用相同的 props 渲染了两次。

Create New Event被点击/events时组件渲染

here is the live sandbox

  • 位于/components/Event/CreateEvent/CreateEvent.js的子组件

  • 父组件位于/Pages/Event/Event.js行号999',子组件从这里被触发

代码如下:

import React from "react";
import AuthContext from "../../context/global-context";
import CreateEvent from "../../components/Event/CreateEvent/CreateEvent";

function Events({ location }) {

  // Sate Managing
  const [allEvents, setAllEvents] = React.useState([]);
  const [creating, setCreating] = React.useState(false);

  // Context As State
  const { token, email } = React.useContext(AuthContext);

  // Creating Event Showing
  const modelBoxHandler = () => {
    // works on when the ViewEvent is open
    if (eventSelected) {
      setEventSelected(null);
      return;
    }

    setCreating(!creating);
  };

  return (
    <div className="events">

      {/* New Event Creating */}
      {creating && (
        <CreateEvent onHidder={modelBoxHandler} allEvents={allEvents} />
      )}

      {console.log("Event Rendered.js =>")}

    </div>
  );
}

export default React.memo(Events, () => true);

Rect 备忘录没有 props 的子组件:

import React from "react";
import AuthContext from "../../../context/global-context";

function CreateEvent({ onHidder, allEvents }) {
  // Context
  const { token } = React.useContext(AuthContext);

  console.log("CreatedEvent.js REnder");
  return (
       ... Some code here
  );
}

export default React.memo(CreateEvent, (prevProps, nextProps) => {
  console.log("Hello", prevProps, nextProps);
});

提前感谢您宝贵的回答和时间!

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    问题在于,基于creating 变量,您实际上是在重新安装而不是呈现 CreateEvent 组件。意思是如果创建变量发生变化,组件在create为真时卸载并重新挂载,所以不是重新渲染

    您还必须注意,modelBoxHandler 函数引用在每次重新渲染时也会发生变化,因此即使您的 CreateEvent 组件处于渲染状态并且父组件由于某种原因重新渲染,CreateEvent 组件也会重新渲染

    您需要进行 2 项更改才能使其更好地工作

    • 使用 useCallback 挂钩定义 modelBoxHandler
    • 在createEvent中根据create prop进行条件渲染
    
     // Creating Event Showing
      const modelBoxHandler = useCallback(() => {
        // works on when the ViewEvent is open
        if (eventSelected) {
          setEventSelected(null);
          return;
        }
    
        setCreating(prevCreating => !prevCreating);
      }, [eventSelected]);
       ...
        return (
            <div className="events">
    
              {/* New Event Creating */}
              <CreateEvent creating={creating} onHidder={modelBoxHandler} allEvents={allEvents} />
    
              {console.log("Event Rendered.js =>")}
    
            </div>
        );
    
    

    在 createEvent 中

    function CreateEvent({ onHidder, allEvents, creating }) {
      // Context
      const { token } = React.useContext(AuthContext);
    
      console.log("CreatedEvent.js REnder");
      if(!creating) {
         return null;
      }
      return (
           ... Some code here
      );
    }
    
    export default React.memo(CreateEvent);
    

    【讨论】:

      【解决方案2】:

      在您的示例中,您没有额外的渲染以供 React.memo 工作。

      根据你的渲染逻辑,没有nextProps,你用条件渲染卸载组件(creating)。

      // You toggle with `creating` value, there is only single render each time
      creating && <CreateEvent onHidder={modelBoxHandler} allEvents={allEvents}/>
      
      // Works, because there will be multiple renders (nextProps)
      true && <CreateEvent onHidder={modelBoxHandler} allEvents={allEvents} />
      

      在这种情况下,您可能不需要React.memo

      【讨论】:

        猜你喜欢
        • 2021-08-05
        • 2020-03-28
        • 1970-01-01
        • 2021-03-10
        • 2020-03-23
        • 1970-01-01
        • 2021-04-08
        • 1970-01-01
        • 2018-11-28
        相关资源
        最近更新 更多