简体   繁体   中英

react memo is not getting props

React memo isn't capturing the props neither the prevProps nor the nextProps and the component render well. The react docs say

  • If your function component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost.

my problem is to stop twice rendering using react memo, but memo seems to be not working and the component renders twice with the same props.

The component renders when the Create New Event is clicked on /events

here is the live sandbox .

  • Child Component located at /components/Event/CreateEvent/CreateEvent.js

  • the parent component is located at /Pages/Event/Event.js line number 999 ' from where the child component is being triggered

Here is the Code:

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

Child Component where the Rect memo doesn't have 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);
});

Thanks in advance for your valuable answer and times!

In your example, you don't have an additional render for React.memo to work.

According to your render logic, there aren't any nextProps , you unmount the component with conditional rendering ( 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} />

In this case, you might not need React.memo .

The problem is that on basis of creating variable you are actually remounting and not rendering the CreateEvent component. What it means is that if creating variable changes, the component is unmounted and re-mounted when creating is true, so its not a re-render

Also you must note that modelBoxHandler function reference also changes on each re-render so even if your CreateEvent component is in rendered state and the parent re-rendered due to some reason, the CreateEvent component too will re-render

There are 2 changes that you need to make to make it work better

  • Define modelBoxHandler with a useCallback hook
  • perform conditional rendering in createEvent based on creating 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>
    );

and in 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM