1
\$\begingroup\$

I have been working on React and would like to know best practices for separating smart and dumb components.

This example is a Parent controls state, but I have put the button UI in render. Should these go into child and implemented back to parent via callback or is that overkill?

class Child extends React.Component { 
      constructor(props){
      super(props);
      }
      render() {
      return (
         <div><p>I said {this.props.greeting} {this.props.count} times</p>    
        </div>
        );
      }
    }

    class Parent extends React.Component {
      constructor() {
        super();
        this.state = { 
          count: 0,
          greeting: "Hello"
        };
      }

      sayHello() {
        this.setState((prevState, props) => {
        return { 
          count: prevState.count + 1,
              greeting: "Hello"
               }
        }                   
      )};
        sayGoodBye() {
        this.setState((prevState, props) => {    
        return {       
          count: this.count = 1,
          greeting: "Goodbye"
               }
        }                   
      )};



      render() {
        return (
          <div>
            <button onClick={() => this.sayHello() }>Say Hello</button>
            <button onClick={() => this.sayGoodBye() }>Say Goodbye</button>
          <Child count={this.state.count} greeting={this.state.greeting} />
            </div>
        )

      }
    }

    ReactDOM.render(<Parent />, document.getElementById('app'));
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Seems like you got a good start.

Consider refactoring components that do not keep state into a "functional component". More about functional components here. This is a simple JavaScript arrow function that returns what you would like the component to render, based on your props. The function will take the prop-object as an argument. In your case it would become:

const Child = (props) => (
    <div>
        <p>I said {props.greeting} {props.count} times</p>    
    </div>
)

Or even simpler using destructuring from Ecmascript 2015. Notice that we can retrieve the attributes of the prop-object directly in the function parameters.

const Child = ({greeting, count}) => (
    <div>
        <p>I said {greeting} {count} times</p>    
    </div>
)

I think your parent component is fine. You are separating the concerns of the buttons and text output neatly and there is no need to move the buttons into the Child component. This is obviously a simple example, in more complex cases it might make sense to encapsulate the elements inside another component in order to prevent re-rendering or because of functional cohesion. In this case it would perhaps be overkill.

\$\endgroup\$
2
  • \$\begingroup\$ Why is it recommended to use functional components when possible ? \$\endgroup\$ Jun 21, 2017 at 12:05
  • 1
    \$\begingroup\$ In my opinion, the reduction of code is the biggest win. It "forces" you to structure your components in a way that I have found to easier to reason about. Generally, pure functions (where the return value is soley based in the parameter inputs and that do not produce side-effects) produce less bugs. A more in-depth answer can be found here: hackernoon.com/… and medium.com/javascript-scene/… \$\endgroup\$
    – Matt
    Jun 25, 2017 at 19:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.