freeCodeCamp/guide/english/react/react-props-state/index.md

166 lines
5.2 KiB
Markdown
Raw Normal View History

2018-10-12 19:37:13 +00:00
---
title: React Props and State
---
## Props & State
There are two types of data that control a component: props and state. Props are set by the parent and they are fixed throughout the lifetime of a component. For data that is going to change, we have to use state.
### Props
Most components can be customized with different parameters when they are created. These creation parameters are called `props`.
Your own components can also use props. This lets you make a single component that is used in many different places in your app, with slightly different properties in each place. Refer to `this.props` in your render function:
```
class Welcome extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
const element = <Welcome name="neel" />;
```
The line `<Welcome name="neel" />` creates a property name with value `"neel"`.
the property is passed to the component, similar to how an argument is passed to a function. In fact, we could even rewrite the component to be simpler:
```
function Welcome(props) {
return <h1>Hello {props.name}</h1>;
}
```
We can make the name property optional by adding defaultProps to the Welcome class:
```
class Welcome extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
Welcome.defaultProps = {
name: "world",
};
```
If Welcome is called without a name it will simply render `<h1> Hello world</h1>`.
So `props` can come from the parent, or can be set by the component itself.
You used to be able to change props with setProps and replaceProps but these have been **deprecated**. During a components life cycle props should not change (consider them immutable).
Since props are passed in, and they cannot change, you can think of any React component that only uses props (and not state) as “pure,” that is, it will always render the same output given the same input. This makes them really easy to test.
### State
Like `props`, `state` holds information about the component. However, the kind of information and how it is handled is different.
By default, a component has no state. The `Welcome` component from above is stateless:
```
function Welcome(props) {
return <h1>Hello {props.name}</h1>;
}
```
When a component needs to keep track of information between renderings the component itself can create, update, and use state.
Well be working with a fairly simple component to see `state` working in action. Weve got a button that keeps track of how many times youve clicked it.
heres the code:
```
class Button extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}
render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}
}
```
### state is created in the component
Lets look at the `constructor` method:
```
constructor() {
super();
this.state = {
count: 0,
};
}
```
This is where state gets its initial data. The inital data can be hard coded (as above), but it can also come from `props`.
### `state` is changeable
Heres `updateCount` method:
```
updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}
```
We change the state to keep track of the total number of clicks. The important bit is setState. First off, notice that setState takes a function, thats becuase setState can run asynchronously. It needs to take a callback function rather than updating the state directly. You can see we have access to prevState within the callback, this will contain the previous state, even if the state has already been updated somewhere else.
React goes one step better, setState updates the `state` object **and** re-renders the component automagically.
### `state` warnings
> It is tempting to write `this.state.count = this.state.count + 1`.
**Don't do this** React cannot listen to the state getting updated in this way, so your component will not re-render. Always use `setState`.
It might also be tempting to write something like this:
```
// DO NOT USE
this.setState({
count: this.state.count + 1
});
```
Although this might look reasonable, doesnt throw errors, and you might find examples that use this syntax online, it is wrong. This does not take into account the asychronous nature that `setState` can use and might cause errors with out of sync state data.
### Program Continue !!!
And finally, `render`
```
render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}
```
`onClick={() => this.updateCount()}` means that when the button is clicked the updateCount method will be called. We need to use **ES6s arrow function** so updateCount will have access to this instances state.
The text rendered in the button is `Clicked {this.state.count} times`, which will use whatever this.state.count is at the time of rendering.
More Info about: <a href='https://facebook.github.io/react-vr/docs/components-props-and-state.html' target='_blank' rel='nofollow'>**React props and state**</a>