Hello everyone, continue to learn about ReactJs series today, I would like to introduce to you two things I think are the most interesting of ReactJs are State
and Props
.
1. State
State you can simply understand is a place where you store Component data, from which you can pass data to the components in the Component and to other Components. We should minimize State as much as possible and limit the number of Components using State. For example, if there are 10 Components that need to use data from State, then instead of storing data in all 10 Components, we should create a parent component to store data of all, then state management will be easier. . You will find that effective State management is of utmost importance as your application grows larger and more complex and logic becomes more complex.
Using State
The following example will show you how to use State in ReactJs:
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import React from 'react'; class App extends React.Component { constructor(props) { super(props); this.state = { header: "Header from state...", content: "Content from state..." } } render() { return ( <div> <h1>{this.state.header}</h1> <h2>{this.state.content}</h2> </div> ); } } export default App; |
main.js
1 2 3 4 5 6 | import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(<App />, document.getElementById('app')); |
2. Props
The main difference between state and props is that props are immutable. That is why the parent component should define state that can change its value, while child component should only use data from parent component and cannot change its value.
Using props
When we want to assign the value of Props from the parent Component to the child Component we just need to add the properties and value when calling the child Component from the parent Component:
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import React from 'react'; class App extends React.Component { render() { return ( <div> <h1>{this.props.headerProp}</h1> <h2>{this.props.contentProp}</h2> </div> ); } } export default App; |
When calling this.props.headerProp
in App
, it will look for the value of the corresponding props – here is headerProp
assigned in the parent component.
main.js
1 2 3 4 5 6 7 8 9 | import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(<App headerProp = "Header from props..." contentProp = "Content from props..."/>, document.getElementById('app')); export default App; |
As we can see, the App
component is assigned 2 props namely headerProp = "Header from props..."
and contentProp = "Content from props..."
.
Default props
You can assign a default value to props instead of having to assign a value to it from the parent Component with the defaultProps
method:
App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import React from 'react'; class App extends React.Component { render() { return ( <div> <h1>{this.props.headerProp}</h1> <h2>{this.props.contentProp}</h2> </div> ); } } App.defaultProps = { headerProp: "Header from props...", contentProp:"Content from props..." } export default App; |
This usage will also produce the same result as above.
State and Props
The following example will help you imagine how to use the basic combination of State and Props in the application. We assign a value to the state in Component and pass that value to the child Component using props. Under the child Component, getting the value of props will be the same as usual thí.props.{Tên props}
.
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import React from 'react'; class App extends React.Component { constructor(props) { super(props); this.state = { header: "Header from props...", content: "Content from props..." } } render() { return ( <div> <Header headerProp = {this.state.header}/> <Content contentProp = {this.state.content}/> </div> ); } } class Header extends React.Component { render() { return ( <div> <h1>{this.props.headerProp}</h1> </div> ); } } class Content extends React.Component { render() { return ( <div> <h2>{this.props.contentProp}</h2> </div> ); } } export default App; |
main.js
1 2 3 4 5 6 | import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(<App/>, document.getElementById('app')); |
The result will be similar to the two cases above, the only difference is that we assign a value to props from the value of state. The property of state is mutable so when you want to change the value of props you just need to change the value of state, when the value of the props in the child Component will also be changed according to the value of State .
3. Props validation
Using the validation property is a great way to validate component values. It will help avoid errors during application development and also make components more readable when it determines the usage of the components in advance.
Validating Props
In the example below, we’ll create the App component with all the props we need to use. App.propTypes
is used to validate props. If one of the values of props does not meet the validate condition an error message will be displayed in the console. We’ll create a default value for the props to check for the validates made. If the value of the props pass validate then its value will be displayed, otherwise an error message will be displayed in the console.
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import React from 'react'; class App extends React.Component { render() { return ( <div> <h3>Array: {this.props.propArray}</h3> <h3>Bool: {this.props.propBool ? "True..." : "False..."}</h3> <h3>Func: {this.props.propFunc(3)}</h3> <h3>Number: {this.props.propNumber}</h3> <h3>String: {this.props.propString}</h3> <h3>Object: {this.props.propObject.objectName1}</h3> <h3>Object: {this.props.propObject.objectName2}</h3> <h3>Object: {this.props.propObject.objectName3}</h3> </div> ); } } App.propTypes = { propArray: React.PropTypes.array.isRequired, propBool: React.PropTypes.bool.isRequired, propFunc: React.PropTypes.func, propNumber: React.PropTypes.number, propString: React.PropTypes.string, propObject: React.PropTypes.object } App.defaultProps = { propArray: [1,2,3,4,5], propBool: true, propFunc: function(e){return e}, propNumber: 1, propString: "String value...", propObject: { objectName1:"objectValue1", objectName2: "objectValue2", objectName3: "objectValue3" } } export default App; |
main.js
1 2 3 4 5 6 | import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(<App/>, document.getElementById('app')); |
4. Component API
In this section, we will learn about React Component APi. We will discuss three methods: setState()
, forceUpdate
and ReactDOM.findDOMNode()
. In ES6, we will use this.emthod.bind(this)
in the examples below.
Set State
setState()
is the method to update the value of state in the component. It won’t remove the state, it just changes its value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import React from 'react'; class App extends React.Component { constructor() { super(); this.state = { data: [] } this.setStateHandler = this.setStateHandler.bind(this); }; setStateHandler() { var item = "setState..." var myArray = this.state.data.slice(); myArray.push(item); this.setState({data: myArray}) }; render() { return ( <div> <button onClick = {this.setStateHandler}>SET STATE</button> <h4>State Array: {this.state.data}</h4> </div> ); } } export default App; |
Initially the value of data
is an empty array. Each time the user clicks the button, the value of data
is added to the new value setState...
If we click three times the value of data will be: data = ["setState...", "setState...", "setState..."]
.
Find Dom Node
For DOM tree manipulation, we can use the ReactDOM.findDOMNode()
method. First we need to import ‘react-dom’.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import React from 'react'; import ReactDOM from 'react-dom'; class App extends React.Component { constructor() { super(); this.findDomNodeHandler = this.findDomNodeHandler.bind(this); }; findDomNodeHandler() { var myDiv = document.getElementById('myDiv'); ReactDOM.findDOMNode(myDiv).style.color = 'green'; } render() { return ( <div> <button onClick = {this.findDomNodeHandler}>FIND DOME NODE</button> <div id = "myDiv">NODE</div> </div> ); } } export default App; |
Now when the user clicks on the button the element with id = “myDiv” will turn green.
5. Component Life Cycle
In this section we learn about the component’s Life Cycle.
Lifecycle methods
componentWillMount
will be executed before the component is rendered, on both the server and client side.componentDidMount
will be executed when the componet is rendered on the client side only. This is where calls for AJAX requests and DOM or update state. It is also used when calling other JavaScript frameworks and delay functions such assetTimeout
orsetInterval
.componentWillReceiveProps
is executed as soon as the props value is updated and before other renderings are called. We activate it fromsetNewNumber
when the state is updated.shouldComponentUpdate
will returntrue
orfalse
. It will determine whether the component will be updated or not. Its value is set to the default value oftrue
. If you’re sure the component doesn’t need to be re-rendered when the state or props are updated, you can returnfalse
.componentWillUpdate
will be called before rendering.componentDidUpdate
will be called after rendering.componentWillUnmount
will be called after unmounting the component from the DOM.
OK, for today’s post, see you all in the next post in the ReactJs series from basic to advanced.
6. References
The above article content is referenced in the ReactJs tutorial series: https://www.tutorialspoint.com/reactjs/index.htm