官术网_书友最值得收藏!

State in React

Every React component has something called state. You can think of this as the configuration of the component at a certain point of time.

Take, for example, a heart icon that turns red when you click on it, as in the case of Twitter. The button has two states: unclicked and clicked. Clicking on the button causes its state, and thus its appearance, to change.

That's the flow in React; user actions or events cause the component state to change, which causes the component's appearance to change.

The preceding statement comes with an enormous helping of "Well, not always…," but it's a useful starting point to understand state:

User event -> State change -> Appearance change

Let's add some state to our LoginContainer, and then go from there.

State is easy to define; it's an object that is the property of the class. We can define it as shown:

class LoginContainer extends Component {
state = { text: ‘Hello from state!’ }

render() {

We always define state at the top of our component.

We can then access our state right in the render method:

class LoginContainer extends Component {
state = { text: ‘Hello from state!’ };

render() {
return (
<div id="LoginContainer" className="inner-container">
<div id="Header">
<img src="/assets/icon.png" alt="logo" />
<h1>{this.state.text}</h1>
</div>

In the preceding code, the curly braces inside JSX mean we're inserting some Javascript code.

This is how we initialize our state, but this state isn't very useful, since there’s no mechanism for changing it.

What we need to do is to provide a way to respond to user events, and modify the state based on them.

What if the text changed when the user clicked on Hello from state!?

Let's add an onClick property to our h1 tag, as follows:

<h1 onClick={this.handleClick}>{this.state.text}</h1>

It references a method on our class called handleClick, which we can define as shown:

class LoginContainer extends Component {
state = { text: 'Hello from state!' };

handleClick = () => {
this.setState({ text: 'State changed!' });
};

render() {

Inside handleClick, we want to change our state. We can do that in React via a function called this.setState, into which we pass the new state object.

Try it out! When you click on Hello from state!, it should immediately change to the new text.

So, how does this work? What setState does is to take the object passed in as an argument and merge it into the current state (if you have multiple properties in state but only pass in an object with one property to setState, it'll change only that property, rather than overwriting the rest). Then, it calls the render() method again, and our component is updated in the DOM to reflect the new state.

If this seems confusing, don't worry, we have a couple more examples to go through, so you’ll get a bit more practice with component state.

Our LoginContainer will have two pieces of state, one to go with each <input> tag. We will store what the user types in the email and password fields in state so that when they submit the form, we can access them.

"Hold on Scott," you may say, "Why don't we just reach into the DOM and grab the value of each input when the user submits the form, the jQuery way?"

We can certainly do that, but it will break the React flow, which is as follows:

User edits input -> Update state -> Re-render input to reflect new value.

This way, our input's value is stored in state and the view is kept in sync with it, rather than having our input's value stored as a property of a DOM element, and accessed when needed.

The advantage of this approach may not seem obvious at this point, but it makes our code much more explicit and understandable.

So, in the preceding flow, we need to update our state whenever the user changes an input. First, let's change how our state initializes:

state = { email: '', password: '' };

Then, let's delete handleClick and add the handleEmailChange and handlePasswordChange methods to our component:

 handleEmailChange = (event) => {
this.setState({ email: event.target.value });
};

handlePasswordChange = (event) => {
this.setState({ password: event.target.value });
};

The preceding methods take in an event (the user typing in the field), grab the value from the event, and then set state to that value.

Again, note that we don't have to define both the email and password every time we call setState; it will merge in the changes to the existing state object without overwriting the other values.

Okay, now the last step. Let's add the onChange properties to our inputs, which call our change handlers. Another crucial step is that our input's value must be derived from state. We can do so like this:

<input
type="text"
onChange={this.handleEmailChange}
value={this.state.email}
placeholder="Your email"
/>
<input
type="password"
onChange={this.handlePasswordChange}
value={this.state.password}
placeholder="Your password"
/>
You can reset your h1 to <h1>Chatastrophe</h1>.

If everything worked out, you should note no change in how your input functions (if there's a typo in your code, you won't be able to type in one or the other). Let's ensure that it's actually working by adding a handler for when our form submits:

<form onSubmit={this.handleSubmit}>

And our method:

handleSubmit = (event) => {
event.preventDefault();
console.log(this.state);
};

The preceding method will just log out the state for us when the user submits the form (clicks on the button), and prevent the form from actually submitting.

Try typing in both fields and then click on Submit. You should see a console log with the state object:

Object { email: "email@email.com", password: "asdfas" }

We did it! Our first React component with state.

I hope you've gotten a sense of the React data flow. Our application has state (stored in different components), which updates in response to events (often user-initiated), which causes parts of our application to rerender in response to the new state:

Events -> State changes -> Re-render.

It's a simple pattern once you wrap your head around it, and makes it easy to trace why your application looks the way it does at any point of time.

主站蜘蛛池模板: 贵德县| 绍兴市| 苏尼特左旗| 永寿县| 威远县| 株洲县| 方山县| 乐至县| 车险| 肥西县| 孝昌县| 二手房| 周至县| 阜南县| 韶山市| 洪雅县| 阆中市| 黎平县| 同心县| 张家口市| 宁津县| 定兴县| 绥化市| 宜章县| 雅江县| 蒲城县| 江达县| 甘谷县| 辉南县| 慈溪市| 承德市| 四平市| 鄂托克旗| 建始县| 长丰县| 唐山市| 黄山市| 通州市| 杨浦区| 永昌县| 星子县|