o7planning

ReactJS props and state Tutorial with Examples

  1. Hint
  2. ReactJS props
  3. ReactJS state
  4. ReactJS state (2)

1. Hint

In this lesson, I am going to explain on the "props" and "state"concepts in React and compare the difference between"props" and "state".
If you are the beginner of React, you should refer to the first lesson of React by the following path. It will help you establish the environment for React and run the "Hello React" example successfully.

2. ReactJS props

"props" stands for "properties", but it is a concept in the ReactJS. Basically, the props is an object. It stores the values of attributes of a Tag.
We need to clarify what the props concept means through examples.
OK, first example: on a directory, create 2 files such as props-example.jsx & props-example.html.
props-example.jsx
// Create a ES6 class component
class Greeting extends React.Component {
  // Use the render function to return JSX component
  render() {
    return (
      <div className="greeting">
         <h3>Hello {this.props.fullName}</h3>
      </div>
      );
    }
}

const element1 = document.getElementById('greeting1')

// Use the ReactDOM.render to show your component on the browser
ReactDOM.render(
    <Greeting fullName='Tran' />,
    element1
)
props-example.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">

      <title>ReactJS Props</title>
      <script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
      <style>
         .greeting {
           border: 1px solid #bdbcae;
           background-color: #fbfad9;
           margin: 5px 0px;
           padding: 5px;
         }
      </style>
   </head>
   <body>
      <h1>Props example:</h1>
      <div id="greeting1"></div>

      <script src="props-example.jsx" type="text/babel"></script>

   </body>
</html>
Start your HTTP Server and run the props-example.html file and you receive the results like the following illustration:
In ReactJS, when you create a Component, it is like the creation of your own new tag by you. Each property of Component will correspond to an attribute of tag. (See the following illustration).
The value of attribute (Of tag) will be passed to the property of Component. However, you can create default values for properties.
OK, next example: In this example, you create a Component with its properties which will be assigned default values:
props-example2.jsx
class Welcome extends React.Component {

  render() {
    return (
      <div className="welcome">
         <h3>Hi {this.props.name}!</h3>
         <i>{this.props.message}</i>
      </div>
      );
    }
}
// Default values of props
Welcome.defaultProps = {
   name: "There",
   message:"Welcome to Website!"
}

const element1 = document.getElementById('welcome1')
const element2 = document.getElementById('welcome2')


ReactDOM.render(
    <Welcome name='Tran' message='Welcome back!' />,
    element1
)

ReactDOM.render(
    <Welcome />,
    element2
)
props-example2.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">

      <title>ReactJS Props</title>
      <script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
      <style>
         .welcome {
           border: 1px solid #bdbcae;
           background-color: #fbfad9;
           margin: 5px 0px;
           padding: 5px;
         }
      </style>
   </head>
   <body>
      <h1>Props example:</h1>

      <div id="welcome1"></div>

      <div id="welcome2"></div>

      <script src="props-example2.jsx" type="text/babel"></script>

   </body>
</html>
Run the props-example2.html file:
Create a Component named Welcome, and create values for properties:
If an attribute doesn't appear on the tag, its value is considered as being default:
Conclusion:
  • You can create default values for props.someProp.
  • You can set values for props.someProp from the attribute someProp of tag.
  • From the inside of Component (class), you don't have any ways to assign new values to the props.someProp.
Note: In fact, there are methods for you to change the value of props, for example, setProps(), replaceProps(), but these methods have been deprecated from ReactJS 0.15 version. Thus, basically, it is possible to conclude that the props is immutable.

3. ReactJS state

state is a concept in React. It is like to props. Before comparing the state and the props, please see an example:
state-example.jsx
// Create a ES6 class component
class Button extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      text: "Please Click me!",
      clickCount: 0
    };
  }
  // Method updateCount()
  updateCount() {
    this.setState((prevState, props) => {
      return {
        clickCount: prevState.clickCount + 1,
        text: "Clicked"
      };
    });
  }

  render() {
    return (
      <button onClick={() => this.updateCount()}>
        {this.state.text} : {this.state.clickCount}
      </button>
    );
  }
}

// Render
ReactDOM.render(<Button />, document.getElementById("button1"));

// Render
ReactDOM.render(<Button />, document.getElementById("button2"));
state-example.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">

      <title>ReactJS State</title>
      <script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>

   </head>
   <body>
      <h1>State example:</h1>

      <div id="button1"></div>
      <br>
      <div id="button2"></div>

      <script src="state-example.jsx" type="text/babel"></script>

   </body>
</html>
Run the state-example.html file on HTTP and see how it works.
Warning
You can not set a new value for the state by the following ways because the React doesn't listen to the change of state by this way, therefore, the Component will not be re-rendered on interface.
Error!!
// Do not do this:
this.state.clickCount = this.state.clickCount + 1

// And do not do this:
this.setState({
  clickCount: this.state.clickCount + 1
});
Conclusion:
  • props.someProp corresponds with an attribute of the tag but state.someState doesn't.
  • You can create default values for state.someState in the constructor of class (Component).
  • In Component (class), you can not change the value of props.someProp, but can change the values of state.someState.

4. ReactJS state (2)

OK, the next example. In this example, we will create an two-way relationship between the values of an <input> and a state:
When the status of Component changes, the ReactJS will re-render this Component on the interface. When the user changes the content on the <input> element, this value will be updated for the state object of the Component via the onChange event.
state-example2.jsx
class Search extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      searchText: "",
      searchCount: 0,
      resultCount: 0
    };
  }

  changeSearchText(event) {
    var v = event.target.value;
    this.setState((prevState, props) => {
      return {
        searchText: v
      };
    });
  }

  doSearch() {
    this.setState( (prevState, props) => {
      var count = this.state.searchText.length * 3;
      return {
        searchCount: prevState.searchCount + 1,
        resultCount: count
      };
    });
  }

  render() {
    return (
      <div className='search-box'>
        <input
          type="text"
          value={this.state.searchText}
          onChange={this.changeSearchText.bind(this)}
        />
        <button onClick={this.doSearch.bind(this)}>Search</button>
        <div>Search Text: {this.state.searchText}</div>
        <div>Search Count: {this.state.searchCount}</div>
        <div>Result Count: {this.state.resultCount}</div>
      </div>
    );
  }
}

// Render
ReactDOM.render(<Search />, document.getElementById("search1"));
state-example2.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">

      <title>ReactJS State</title>
      <script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
      <style>
         .search-box {
           border:1px solid #cbbfab;
           padding: 5px;
         }
      </style>
   </head>
   <body>
      <h1>State example:</h1>

      <div id="search1"></div>

      <script src="state-example2.jsx" type="text/babel"></script>

   </body>
</html>
Run the state-example2.html file on HTTP Server and see the way how it works.