0

I have a case where I need to update the parent before showing a modal in a child (portaled to the end anyways).

I wish to have a sequence where:

  1. The parent updates a state
  2. The parent re-renders to update some DOM elements (with unchanged child)
  3. Child updates a state or receives prop
  4. Child re-renders to show the modal

I know in a more general case, I can use react-transition-groups to show the modal with a delay. But I'm using a third-party modal and its events are not exposed to me. I would like to avoid writing my own modal since it's used extensively and it'd be a pain to refactor all of them.

Related: Does React keep the order for state updates?

no matter how many setState() calls in how many components you do inside a React event handler, they will produce only a single re-render at the end of the event.


The dumb part of the question asked at 3am

This is what I have right now:

Component:

Components: 

<Parent>
    {!this.state.hideOtherThing && <div />
    <Child showThing={this.state.hideOtherThing} />
</Parent>
Pseudo Code:
class Parent extends React.Component {
    ...
    hideOtherThing = () => {
        // make changes to hide other things...
        ...
        this.setState({ hideOtherThing: true }, 
        // callback, should be executed first?
        () => console.log("setState", this.state.hideOtherThing));
    }
    ...
}

class Child extends React.Component {
    ...
    componentDidUpdate(prevProps) {
        if (prevProps.showThing === false && this.props.showThing === true) {
            console.log("child update", this.props.showThing);
        }
    }
    ...
    render() {
        console.log("child render", this.props.showThing);
        return...
    }
}

On update, I was hoping for something like

"child render" false // previous state
"setState" true
"child update" true
"child render" true

However, I got the exact opposite:

"child render" false // previous state
"child render" true
"child update" true
"setState" true

I tried to use the prop directly; I tried to set a child state from props; I tried setTimeout, but it seems the child is fixated on updating first. How do I render child changes after parent changes?

Samson Liu
  • 460
  • 4
  • 20
  • In React, a component ***necessarily*** renders its children first in order to compute and return its render result to its parent, and so on. Also, don't use a console.log in the `render` method, it should be a pure function. State updates are also handled asynchronously. – Drew Reese Aug 10 '21 at 07:23
  • @DrewReese I realized I'm asking a very dumb question at 3am lmao. I have a weird case I need to solve and apparently I'm in too deep. I'll see if I can restructure the code in some way tomorrow. – Samson Liu Aug 10 '21 at 07:25
  • Feel free to edit/update your question if you have new details or more relevant information for your question/issue/use case. – Drew Reese Aug 10 '21 at 07:28
  • 1
    When (1) parent update state happens it will (2) trigger rerendering. It will necessarily rerender its VirtualDOM sub-tree (i.e. children). If part of the parent updating involves passing new props to children then they will OFC also (3) update state/receive props and (4) also rerender (*same process from 1 with their children*). I believe this is indicative of a logical flow issue in the parent if you are trying to invert how React renders out the VirtualDOM. Can you share a [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) code example for what you are trying to do? – Drew Reese Aug 10 '21 at 15:50

0 Answers0