反应备忘录没有获得道具

时间:2020-06-09 05:44:14

标签: javascript reactjs react-hooks

React备忘录无法捕获prevPropsnextProps的道具,并且组件不能很好地渲染。反应文档说

  • 如果给定相同的道具,功能组件呈现相同的结果,则可以将其包装在对React.memo的调用中,以提高性能。

我的问题是使用react 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备忘录没有道具的子组件:

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);
});

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

2 个答案:

答案 0 :(得分:1)

在您的示例中,没有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

答案 1 :(得分:1)

问题在于,根据creating变量,您实际上是重新安装而不渲染 CreateEvent组件。它的意思是,如果创建变量发生更改,则在创建时会卸载该组件并将其重新安装为true,因此它不会重新渲染

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

您需要进行2处更改以使其更好地工作

  • 使用useCallback挂钩定义modelBoxHandler
  • 基于创建道具在createEvent中执行条件渲染

 // 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);