Benefits of composition over inheritance in React












2















I'm having a hard time substituting inheritance for composition in React. I'll try to explain the problem posed and my current solution, based on inheritance which is discouraged in the React style guide.



First, I define common state and methods in a super component:



export default class SuperComponent extends Component {
constructor(props) {
super(props);
this.state = commonState;
}

foo() {
this.setState({a: 3});
}

render() {
return (
<div>
{this.getContent()}
</div>
)
}
}


Then I make subcomponents with potentially more state and methods. These should also have access to the state of the supercomponent though:



export default class SubComponent1 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent1State);
}

bar() {
this.setState({b: 7});
}

getContent() {
return (
<div>
I'm subcomponent 1
</div>
)
}
}

export default class SubComponent2 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent2State);
}

bar() {
this.setState({c: 1});
}

getContent() {
return (
<div>
I'm subcomponent 2
</div>
)
}
}


When I try to convert this into an composition based approach I get this:



export default class SuperComponent extends Component {
foo() {
this.props.setStateMethod({a: 3});
}

render() {
return (
<div>
<div>
{this.props.text}
</div>
</div>
)
}
}

export default class SubComponent1 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent1State);
}

bar() {
this.setState({b: 7});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 1"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}

export default class SubComponent2 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent2State);
}

bar() {
this.setState({c: 1});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 2"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}


Is this a good way to go about converting the inheritance based solution to a composition based one? Isn't the inheritance based one better since common and differentiated state are better separated? In the composition based solution, one has to define common state in every sub component on initialisation.










share|improve this question























  • Common state can be handled by container components hat inject the state as props. This is real separation of state because it is now owned by a dedicated component and others do not need to know how to manage that state. In your example the state of the sub components should be lifted up to the parent if they share that state.

    – trixn
    Jul 31 '18 at 0:14


















2















I'm having a hard time substituting inheritance for composition in React. I'll try to explain the problem posed and my current solution, based on inheritance which is discouraged in the React style guide.



First, I define common state and methods in a super component:



export default class SuperComponent extends Component {
constructor(props) {
super(props);
this.state = commonState;
}

foo() {
this.setState({a: 3});
}

render() {
return (
<div>
{this.getContent()}
</div>
)
}
}


Then I make subcomponents with potentially more state and methods. These should also have access to the state of the supercomponent though:



export default class SubComponent1 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent1State);
}

bar() {
this.setState({b: 7});
}

getContent() {
return (
<div>
I'm subcomponent 1
</div>
)
}
}

export default class SubComponent2 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent2State);
}

bar() {
this.setState({c: 1});
}

getContent() {
return (
<div>
I'm subcomponent 2
</div>
)
}
}


When I try to convert this into an composition based approach I get this:



export default class SuperComponent extends Component {
foo() {
this.props.setStateMethod({a: 3});
}

render() {
return (
<div>
<div>
{this.props.text}
</div>
</div>
)
}
}

export default class SubComponent1 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent1State);
}

bar() {
this.setState({b: 7});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 1"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}

export default class SubComponent2 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent2State);
}

bar() {
this.setState({c: 1});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 2"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}


Is this a good way to go about converting the inheritance based solution to a composition based one? Isn't the inheritance based one better since common and differentiated state are better separated? In the composition based solution, one has to define common state in every sub component on initialisation.










share|improve this question























  • Common state can be handled by container components hat inject the state as props. This is real separation of state because it is now owned by a dedicated component and others do not need to know how to manage that state. In your example the state of the sub components should be lifted up to the parent if they share that state.

    – trixn
    Jul 31 '18 at 0:14
















2












2








2








I'm having a hard time substituting inheritance for composition in React. I'll try to explain the problem posed and my current solution, based on inheritance which is discouraged in the React style guide.



First, I define common state and methods in a super component:



export default class SuperComponent extends Component {
constructor(props) {
super(props);
this.state = commonState;
}

foo() {
this.setState({a: 3});
}

render() {
return (
<div>
{this.getContent()}
</div>
)
}
}


Then I make subcomponents with potentially more state and methods. These should also have access to the state of the supercomponent though:



export default class SubComponent1 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent1State);
}

bar() {
this.setState({b: 7});
}

getContent() {
return (
<div>
I'm subcomponent 1
</div>
)
}
}

export default class SubComponent2 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent2State);
}

bar() {
this.setState({c: 1});
}

getContent() {
return (
<div>
I'm subcomponent 2
</div>
)
}
}


When I try to convert this into an composition based approach I get this:



export default class SuperComponent extends Component {
foo() {
this.props.setStateMethod({a: 3});
}

render() {
return (
<div>
<div>
{this.props.text}
</div>
</div>
)
}
}

export default class SubComponent1 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent1State);
}

bar() {
this.setState({b: 7});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 1"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}

export default class SubComponent2 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent2State);
}

bar() {
this.setState({c: 1});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 2"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}


Is this a good way to go about converting the inheritance based solution to a composition based one? Isn't the inheritance based one better since common and differentiated state are better separated? In the composition based solution, one has to define common state in every sub component on initialisation.










share|improve this question














I'm having a hard time substituting inheritance for composition in React. I'll try to explain the problem posed and my current solution, based on inheritance which is discouraged in the React style guide.



First, I define common state and methods in a super component:



export default class SuperComponent extends Component {
constructor(props) {
super(props);
this.state = commonState;
}

foo() {
this.setState({a: 3});
}

render() {
return (
<div>
{this.getContent()}
</div>
)
}
}


Then I make subcomponents with potentially more state and methods. These should also have access to the state of the supercomponent though:



export default class SubComponent1 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent1State);
}

bar() {
this.setState({b: 7});
}

getContent() {
return (
<div>
I'm subcomponent 1
</div>
)
}
}

export default class SubComponent2 extends SuperComponent {
constructor(props) {
super(props);
this.state = Object.assign(this.state, subComponent2State);
}

bar() {
this.setState({c: 1});
}

getContent() {
return (
<div>
I'm subcomponent 2
</div>
)
}
}


When I try to convert this into an composition based approach I get this:



export default class SuperComponent extends Component {
foo() {
this.props.setStateMethod({a: 3});
}

render() {
return (
<div>
<div>
{this.props.text}
</div>
</div>
)
}
}

export default class SubComponent1 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent1State);
}

bar() {
this.setState({b: 7});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 1"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}

export default class SubComponent2 extends Component {
constructor(props) {
super(props);
this.state = Object.assign(commonState, subComponent2State);
}

bar() {
this.setState({c: 1});
}

render() {
return (
<SuperComponent
text={"I'm subcomponent 2"}
setStateMethod={this.setState}
subComponentState={this.state}
/>
)
}
}


Is this a good way to go about converting the inheritance based solution to a composition based one? Isn't the inheritance based one better since common and differentiated state are better separated? In the composition based solution, one has to define common state in every sub component on initialisation.







reactjs inheritance composition






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jul 31 '18 at 0:02









HansHans

5217




5217













  • Common state can be handled by container components hat inject the state as props. This is real separation of state because it is now owned by a dedicated component and others do not need to know how to manage that state. In your example the state of the sub components should be lifted up to the parent if they share that state.

    – trixn
    Jul 31 '18 at 0:14





















  • Common state can be handled by container components hat inject the state as props. This is real separation of state because it is now owned by a dedicated component and others do not need to know how to manage that state. In your example the state of the sub components should be lifted up to the parent if they share that state.

    – trixn
    Jul 31 '18 at 0:14



















Common state can be handled by container components hat inject the state as props. This is real separation of state because it is now owned by a dedicated component and others do not need to know how to manage that state. In your example the state of the sub components should be lifted up to the parent if they share that state.

– trixn
Jul 31 '18 at 0:14







Common state can be handled by container components hat inject the state as props. This is real separation of state because it is now owned by a dedicated component and others do not need to know how to manage that state. In your example the state of the sub components should be lifted up to the parent if they share that state.

– trixn
Jul 31 '18 at 0:14














2 Answers
2






active

oldest

votes


















1














First off, you should read React's Team response on the matter.



The code is pretty vague, so I can't tell if your case is really special, but I doubt it, so let me tackle the general consensus:



Inheritance and Composition are, in a vacuum, equally useful. In some languages or projects, you'll prefer a common class to inherit from, than a dozen functions to import and call, but in React, mainly because it's component-centric approach, the oposite is true.



Composition keeps React about just two things: props and state. You trust what you receive, act in a predictable way and reflect both props and state in what you render. If you need to change slightly what you render, you can send down different props, maybe even make a component that wraps the first one for that specific use. That component can even have some logic on it's own, and pass it down through render props so you can control the result with even more precision. If you need to wrap different components with this logic you can make a HOC and wrap any component easily. At that point you can make dozens of components that return different things to the same props and can switch between a library of components to display the data and to handle it.



Although things like Render props or HOCs look like different things, they are just techniques that use the already existing component logic and apply it in ways that let you reuse code and still make sense within React. Is it a good solution? Well, it works, but you end up in wrapping hell and juggling twenty concepts that are pretty much the same. That's why there is now a proposal for a paradigm changing new feature that is midway between inheritance and composition. But composition still makes less sense in the React way of doing things.



At the end of the day is just a different way of looking at the same problem. Composition just works better with React, and gives you more control in render to mix and match what you need.



Again, if you have a practical example I could give you a better explanation applying different React techniques, but with your current one, clearly there isn't a good or bad way to do it, since it does nothing. This takes some time tinkering more than an explanation.






share|improve this answer

































    0














    I don't think your solution is the best composition-based solution in this case. Since you want the subcomponents to have their own state (and I assume they will have their own logic), I would use a hoc like this:






    // hoc.js
    const withSuper = (SubComponent) => {
    class WithSuper extends React.Component {
    constructor(props) {
    super(props);

    this.foo = this.foo.bind(this);
    }

    foo() { // could also receive a value
    this.props.setState({ a: 3 });
    }

    render() {
    // Passes to the SubComponent:
    // the state.a as a prop
    // function foo to modify state.a
    // the rest of the props that may be passed from above
    return (
    <SubComponent
    a={this.state.a}
    foo={this.foo}
    {...this.props}
    />
    )
    }
    }

    return WithSuper;
    };


    // SubComponent1.js
    class SubComponent1 extends Component {
    constructor(props) {
    super(props);
    this.state = { b: 0 }; // or anything else
    }

    bar() {
    this.setState({b: 7});
    }

    render() {
    // to access the 'a' value use: this.props.a
    // to modify the 'a' value call: this.props.foo()
    return (
    <div>
    I'm subcomponent 1
    </div>
    );
    }
    }

    export default withSuper(SubComponent1);





    The SubComponent2 would also be wrapped: withSuper(SubComponent2), so it could also access a and foo() props.



    I think this solution is better, because the hoc "Super" encapsulates the behavior of a, and the sub-components only have to worry about modifying their specific state.






    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51603767%2fbenefits-of-composition-over-inheritance-in-react%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      First off, you should read React's Team response on the matter.



      The code is pretty vague, so I can't tell if your case is really special, but I doubt it, so let me tackle the general consensus:



      Inheritance and Composition are, in a vacuum, equally useful. In some languages or projects, you'll prefer a common class to inherit from, than a dozen functions to import and call, but in React, mainly because it's component-centric approach, the oposite is true.



      Composition keeps React about just two things: props and state. You trust what you receive, act in a predictable way and reflect both props and state in what you render. If you need to change slightly what you render, you can send down different props, maybe even make a component that wraps the first one for that specific use. That component can even have some logic on it's own, and pass it down through render props so you can control the result with even more precision. If you need to wrap different components with this logic you can make a HOC and wrap any component easily. At that point you can make dozens of components that return different things to the same props and can switch between a library of components to display the data and to handle it.



      Although things like Render props or HOCs look like different things, they are just techniques that use the already existing component logic and apply it in ways that let you reuse code and still make sense within React. Is it a good solution? Well, it works, but you end up in wrapping hell and juggling twenty concepts that are pretty much the same. That's why there is now a proposal for a paradigm changing new feature that is midway between inheritance and composition. But composition still makes less sense in the React way of doing things.



      At the end of the day is just a different way of looking at the same problem. Composition just works better with React, and gives you more control in render to mix and match what you need.



      Again, if you have a practical example I could give you a better explanation applying different React techniques, but with your current one, clearly there isn't a good or bad way to do it, since it does nothing. This takes some time tinkering more than an explanation.






      share|improve this answer






























        1














        First off, you should read React's Team response on the matter.



        The code is pretty vague, so I can't tell if your case is really special, but I doubt it, so let me tackle the general consensus:



        Inheritance and Composition are, in a vacuum, equally useful. In some languages or projects, you'll prefer a common class to inherit from, than a dozen functions to import and call, but in React, mainly because it's component-centric approach, the oposite is true.



        Composition keeps React about just two things: props and state. You trust what you receive, act in a predictable way and reflect both props and state in what you render. If you need to change slightly what you render, you can send down different props, maybe even make a component that wraps the first one for that specific use. That component can even have some logic on it's own, and pass it down through render props so you can control the result with even more precision. If you need to wrap different components with this logic you can make a HOC and wrap any component easily. At that point you can make dozens of components that return different things to the same props and can switch between a library of components to display the data and to handle it.



        Although things like Render props or HOCs look like different things, they are just techniques that use the already existing component logic and apply it in ways that let you reuse code and still make sense within React. Is it a good solution? Well, it works, but you end up in wrapping hell and juggling twenty concepts that are pretty much the same. That's why there is now a proposal for a paradigm changing new feature that is midway between inheritance and composition. But composition still makes less sense in the React way of doing things.



        At the end of the day is just a different way of looking at the same problem. Composition just works better with React, and gives you more control in render to mix and match what you need.



        Again, if you have a practical example I could give you a better explanation applying different React techniques, but with your current one, clearly there isn't a good or bad way to do it, since it does nothing. This takes some time tinkering more than an explanation.






        share|improve this answer




























          1












          1








          1







          First off, you should read React's Team response on the matter.



          The code is pretty vague, so I can't tell if your case is really special, but I doubt it, so let me tackle the general consensus:



          Inheritance and Composition are, in a vacuum, equally useful. In some languages or projects, you'll prefer a common class to inherit from, than a dozen functions to import and call, but in React, mainly because it's component-centric approach, the oposite is true.



          Composition keeps React about just two things: props and state. You trust what you receive, act in a predictable way and reflect both props and state in what you render. If you need to change slightly what you render, you can send down different props, maybe even make a component that wraps the first one for that specific use. That component can even have some logic on it's own, and pass it down through render props so you can control the result with even more precision. If you need to wrap different components with this logic you can make a HOC and wrap any component easily. At that point you can make dozens of components that return different things to the same props and can switch between a library of components to display the data and to handle it.



          Although things like Render props or HOCs look like different things, they are just techniques that use the already existing component logic and apply it in ways that let you reuse code and still make sense within React. Is it a good solution? Well, it works, but you end up in wrapping hell and juggling twenty concepts that are pretty much the same. That's why there is now a proposal for a paradigm changing new feature that is midway between inheritance and composition. But composition still makes less sense in the React way of doing things.



          At the end of the day is just a different way of looking at the same problem. Composition just works better with React, and gives you more control in render to mix and match what you need.



          Again, if you have a practical example I could give you a better explanation applying different React techniques, but with your current one, clearly there isn't a good or bad way to do it, since it does nothing. This takes some time tinkering more than an explanation.






          share|improve this answer















          First off, you should read React's Team response on the matter.



          The code is pretty vague, so I can't tell if your case is really special, but I doubt it, so let me tackle the general consensus:



          Inheritance and Composition are, in a vacuum, equally useful. In some languages or projects, you'll prefer a common class to inherit from, than a dozen functions to import and call, but in React, mainly because it's component-centric approach, the oposite is true.



          Composition keeps React about just two things: props and state. You trust what you receive, act in a predictable way and reflect both props and state in what you render. If you need to change slightly what you render, you can send down different props, maybe even make a component that wraps the first one for that specific use. That component can even have some logic on it's own, and pass it down through render props so you can control the result with even more precision. If you need to wrap different components with this logic you can make a HOC and wrap any component easily. At that point you can make dozens of components that return different things to the same props and can switch between a library of components to display the data and to handle it.



          Although things like Render props or HOCs look like different things, they are just techniques that use the already existing component logic and apply it in ways that let you reuse code and still make sense within React. Is it a good solution? Well, it works, but you end up in wrapping hell and juggling twenty concepts that are pretty much the same. That's why there is now a proposal for a paradigm changing new feature that is midway between inheritance and composition. But composition still makes less sense in the React way of doing things.



          At the end of the day is just a different way of looking at the same problem. Composition just works better with React, and gives you more control in render to mix and match what you need.



          Again, if you have a practical example I could give you a better explanation applying different React techniques, but with your current one, clearly there isn't a good or bad way to do it, since it does nothing. This takes some time tinkering more than an explanation.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 28 '18 at 15:27

























          answered Nov 28 '18 at 15:20









          Diego NosiDiego Nosi

          565




          565

























              0














              I don't think your solution is the best composition-based solution in this case. Since you want the subcomponents to have their own state (and I assume they will have their own logic), I would use a hoc like this:






              // hoc.js
              const withSuper = (SubComponent) => {
              class WithSuper extends React.Component {
              constructor(props) {
              super(props);

              this.foo = this.foo.bind(this);
              }

              foo() { // could also receive a value
              this.props.setState({ a: 3 });
              }

              render() {
              // Passes to the SubComponent:
              // the state.a as a prop
              // function foo to modify state.a
              // the rest of the props that may be passed from above
              return (
              <SubComponent
              a={this.state.a}
              foo={this.foo}
              {...this.props}
              />
              )
              }
              }

              return WithSuper;
              };


              // SubComponent1.js
              class SubComponent1 extends Component {
              constructor(props) {
              super(props);
              this.state = { b: 0 }; // or anything else
              }

              bar() {
              this.setState({b: 7});
              }

              render() {
              // to access the 'a' value use: this.props.a
              // to modify the 'a' value call: this.props.foo()
              return (
              <div>
              I'm subcomponent 1
              </div>
              );
              }
              }

              export default withSuper(SubComponent1);





              The SubComponent2 would also be wrapped: withSuper(SubComponent2), so it could also access a and foo() props.



              I think this solution is better, because the hoc "Super" encapsulates the behavior of a, and the sub-components only have to worry about modifying their specific state.






              share|improve this answer






























                0














                I don't think your solution is the best composition-based solution in this case. Since you want the subcomponents to have their own state (and I assume they will have their own logic), I would use a hoc like this:






                // hoc.js
                const withSuper = (SubComponent) => {
                class WithSuper extends React.Component {
                constructor(props) {
                super(props);

                this.foo = this.foo.bind(this);
                }

                foo() { // could also receive a value
                this.props.setState({ a: 3 });
                }

                render() {
                // Passes to the SubComponent:
                // the state.a as a prop
                // function foo to modify state.a
                // the rest of the props that may be passed from above
                return (
                <SubComponent
                a={this.state.a}
                foo={this.foo}
                {...this.props}
                />
                )
                }
                }

                return WithSuper;
                };


                // SubComponent1.js
                class SubComponent1 extends Component {
                constructor(props) {
                super(props);
                this.state = { b: 0 }; // or anything else
                }

                bar() {
                this.setState({b: 7});
                }

                render() {
                // to access the 'a' value use: this.props.a
                // to modify the 'a' value call: this.props.foo()
                return (
                <div>
                I'm subcomponent 1
                </div>
                );
                }
                }

                export default withSuper(SubComponent1);





                The SubComponent2 would also be wrapped: withSuper(SubComponent2), so it could also access a and foo() props.



                I think this solution is better, because the hoc "Super" encapsulates the behavior of a, and the sub-components only have to worry about modifying their specific state.






                share|improve this answer




























                  0












                  0








                  0







                  I don't think your solution is the best composition-based solution in this case. Since you want the subcomponents to have their own state (and I assume they will have their own logic), I would use a hoc like this:






                  // hoc.js
                  const withSuper = (SubComponent) => {
                  class WithSuper extends React.Component {
                  constructor(props) {
                  super(props);

                  this.foo = this.foo.bind(this);
                  }

                  foo() { // could also receive a value
                  this.props.setState({ a: 3 });
                  }

                  render() {
                  // Passes to the SubComponent:
                  // the state.a as a prop
                  // function foo to modify state.a
                  // the rest of the props that may be passed from above
                  return (
                  <SubComponent
                  a={this.state.a}
                  foo={this.foo}
                  {...this.props}
                  />
                  )
                  }
                  }

                  return WithSuper;
                  };


                  // SubComponent1.js
                  class SubComponent1 extends Component {
                  constructor(props) {
                  super(props);
                  this.state = { b: 0 }; // or anything else
                  }

                  bar() {
                  this.setState({b: 7});
                  }

                  render() {
                  // to access the 'a' value use: this.props.a
                  // to modify the 'a' value call: this.props.foo()
                  return (
                  <div>
                  I'm subcomponent 1
                  </div>
                  );
                  }
                  }

                  export default withSuper(SubComponent1);





                  The SubComponent2 would also be wrapped: withSuper(SubComponent2), so it could also access a and foo() props.



                  I think this solution is better, because the hoc "Super" encapsulates the behavior of a, and the sub-components only have to worry about modifying their specific state.






                  share|improve this answer















                  I don't think your solution is the best composition-based solution in this case. Since you want the subcomponents to have their own state (and I assume they will have their own logic), I would use a hoc like this:






                  // hoc.js
                  const withSuper = (SubComponent) => {
                  class WithSuper extends React.Component {
                  constructor(props) {
                  super(props);

                  this.foo = this.foo.bind(this);
                  }

                  foo() { // could also receive a value
                  this.props.setState({ a: 3 });
                  }

                  render() {
                  // Passes to the SubComponent:
                  // the state.a as a prop
                  // function foo to modify state.a
                  // the rest of the props that may be passed from above
                  return (
                  <SubComponent
                  a={this.state.a}
                  foo={this.foo}
                  {...this.props}
                  />
                  )
                  }
                  }

                  return WithSuper;
                  };


                  // SubComponent1.js
                  class SubComponent1 extends Component {
                  constructor(props) {
                  super(props);
                  this.state = { b: 0 }; // or anything else
                  }

                  bar() {
                  this.setState({b: 7});
                  }

                  render() {
                  // to access the 'a' value use: this.props.a
                  // to modify the 'a' value call: this.props.foo()
                  return (
                  <div>
                  I'm subcomponent 1
                  </div>
                  );
                  }
                  }

                  export default withSuper(SubComponent1);





                  The SubComponent2 would also be wrapped: withSuper(SubComponent2), so it could also access a and foo() props.



                  I think this solution is better, because the hoc "Super" encapsulates the behavior of a, and the sub-components only have to worry about modifying their specific state.






                  // hoc.js
                  const withSuper = (SubComponent) => {
                  class WithSuper extends React.Component {
                  constructor(props) {
                  super(props);

                  this.foo = this.foo.bind(this);
                  }

                  foo() { // could also receive a value
                  this.props.setState({ a: 3 });
                  }

                  render() {
                  // Passes to the SubComponent:
                  // the state.a as a prop
                  // function foo to modify state.a
                  // the rest of the props that may be passed from above
                  return (
                  <SubComponent
                  a={this.state.a}
                  foo={this.foo}
                  {...this.props}
                  />
                  )
                  }
                  }

                  return WithSuper;
                  };


                  // SubComponent1.js
                  class SubComponent1 extends Component {
                  constructor(props) {
                  super(props);
                  this.state = { b: 0 }; // or anything else
                  }

                  bar() {
                  this.setState({b: 7});
                  }

                  render() {
                  // to access the 'a' value use: this.props.a
                  // to modify the 'a' value call: this.props.foo()
                  return (
                  <div>
                  I'm subcomponent 1
                  </div>
                  );
                  }
                  }

                  export default withSuper(SubComponent1);





                  // hoc.js
                  const withSuper = (SubComponent) => {
                  class WithSuper extends React.Component {
                  constructor(props) {
                  super(props);

                  this.foo = this.foo.bind(this);
                  }

                  foo() { // could also receive a value
                  this.props.setState({ a: 3 });
                  }

                  render() {
                  // Passes to the SubComponent:
                  // the state.a as a prop
                  // function foo to modify state.a
                  // the rest of the props that may be passed from above
                  return (
                  <SubComponent
                  a={this.state.a}
                  foo={this.foo}
                  {...this.props}
                  />
                  )
                  }
                  }

                  return WithSuper;
                  };


                  // SubComponent1.js
                  class SubComponent1 extends Component {
                  constructor(props) {
                  super(props);
                  this.state = { b: 0 }; // or anything else
                  }

                  bar() {
                  this.setState({b: 7});
                  }

                  render() {
                  // to access the 'a' value use: this.props.a
                  // to modify the 'a' value call: this.props.foo()
                  return (
                  <div>
                  I'm subcomponent 1
                  </div>
                  );
                  }
                  }

                  export default withSuper(SubComponent1);






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 28 '18 at 14:31

























                  answered Nov 27 '18 at 18:27









                  pdpinopdpino

                  416




                  416






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51603767%2fbenefits-of-composition-over-inheritance-in-react%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                      Calculate evaluation metrics using cross_val_predict sklearn

                      Insert data from modal to MySQL (multiple modal on website)