Skip to content

Instantly share code, notes, and snippets.

@gaearon
Last active January 11, 2024 16:56
Show Gist options
  • Save gaearon/8fa9fdd2c4197ee0b52894877bf587a4 to your computer and use it in GitHub Desktop.
Save gaearon/8fa9fdd2c4197ee0b52894877bf587a4 to your computer and use it in GitHub Desktop.

A top-level App component returns <Button /> from its render() method.

  1. What is the relationship between <Button /> and this in that Button’s render()?

  2. Does rendering <Button><Icon /></Button> guarantee that an Icon mounts?

  3. Can the App change anything in the Button output? What and how?


Update: answers are here!

@chitchu
Copy link

chitchu commented Sep 29, 2016

What is the relationship between <Button /> and this in that Button’s render()?

this in <Button/>'s render() is a Button React Component object.

Does rendering <Button><Icon /></Button> guarantee that an Icon mounts?

No. Only if the <Button/> component returns props.children in it's render method.

Can the App change anything in the Button output? What and how?

Passing down props or child components to the <Button/>.

@SukantGujar
Copy link

SukantGujar commented Sep 29, 2016

  1. The App component's render method returns a Button Element, which is not the same as Button Component class. This Button element instance has this structure -

    {
        type: Button, // points to the Button Component class since it's a custom Component, not a primitive.
        props:{...}
    }
    

    When the element is actually mounted, React will use this information to create a Button Component class instance, which will be the value of this inside the Button Component's render.

  2. The will be mounted if App has mounted Button and the render of Button returns {this.props.children}.

  3. Yes, App can change what Button renders through props, or using a HOC on it.

@hon2a
Copy link

hon2a commented Sep 29, 2016

  1. <Button /> is a React.Element - a description of what is to be rendered. Most importantly it says that a Button instance is needed for the render and which props should be passed to it. this refers to that Button instance.
  2. No, it only passes <Icon /> to the Button as props.children. What mounts inside the Button depends solely on the Button (namely its render and shouldComponentUpdate).
  3. If by "Button output" you mean the React.Element description returned by its render(), then no. It controls what's passed to Button in props and it can later act on the Button instance, but it has no way to access the React.Element returned from Button's render().

@reel
Copy link

reel commented Sep 29, 2016

  1. this belongs to Button
  2. Button has to explicitly output children
  3. With props

@Rom325
Copy link

Rom325 commented Sep 29, 2016

Regarding the third question, how about an ugly way?

class App extends React.Component{
    render(){
        const button = React.Children.only(this.props.children)
        if (typeof button.type.prototype.render === "function"){
            button.type.prototype.render = () => <span>"Changed completely"</span>;
        }

        return (<div>{ this.props.children } </div>);
    }
}

Btw it won't work for stateless functional components

@danielpetrov
Copy link

1.Q- What is the relationship between and this in that Button’s render()?
1.A- '< Button />' == React.createElement('Button'). Button is created with React.createClass which expects object specification. In those object specification there is render method and this points to that object instance. React.createElement('Button') or '< Button />' creates new instance of that type. So the this in Button's render method is almost the '< Button />' but not exactly. The '< Button />' instance is created via React and not native Object.create().

2.Q- Does rendering

guarantee that an Icon mounts?
2.A- Never. Button may choose to not render it's children.

3.Q- Can the App change anything in the Button output? What and how?
3.A- One way is directly via props. Button also may be connected to some store on which App is connected. Also it can change it directly through passing different children to Button.

@wmira
Copy link

wmira commented Sep 30, 2016

  1. defines the tree..with type as Button. this in Button is the actual instance created based on tree.
  2. No. the in the is just a description of the tree of elements. It is still possible for the Button instance to ignore it.
  3. via props if permitted by Button

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment