標籤:
Last time we looked at how to use properties, to affect the initial rendering of components. Today we’ll take a look at how to use state, how it differs from properties and some things you should consider when using state.
上一次我們討論了如何使用properties來影響一個將要被渲染的組件,今天我們來看一看怎麼使用state,它和properties的區別以及什麼情境下可以使用state。
Like properties, state affects how a component behaves and renders. Unlike properties, there’s no way to define what state should be applied to components via JSX…
像properties一樣,state影響了一個組件如何表現以及渲染,但和properties不同的是,他沒有辦法來通過JSX為定義一個組件的行為。
Properties vs. State
Properties are defined when components are created, whether by JSX or by pure JavaScript. State, on the other hand, is only seen on the inside of component definitions. This is the first, and most important difference between the two.
當一個組件被建立出來的時候,properties也被定義好了不管你是通過pure js還是JSX,而state只能在一個組件的內部可見,這是第一點,但最重要的區別在於第二點。
When you think of properties, you should be thinking of component initialisation. When you think of state, you should think of an internal data-set which affects the rendering of components.
當你思考一個properties的時候,你應該思考的是一個組件的初始化,當你思考一個state的時候,你應該思考的是影響渲染一個組件的資料。
There are ways to validate the presence and type of properties, but there is no such mechanism for state. You, as the developer of a component, are the only person who should know what state your component needs, and the correct data types which should be accepted/provided.
由開發人員來決定什麼state可以被一個組件接受或使用。
State should be considered private data.
state應該被看作是私人資料。
Setting Initial State
Before we can use state, we need to declare a default set of values for the initial state. This is done by defining a method called getInitialState() and returning an object:
在我們能使用state之前,我們需要通過初始化的state來聲明一些預設的值,這個是通過一個叫getInitialState的函數或方法來定義的。
/** * @jsx React.DOM */ var InterfaceComponent = React.createClass({ getInitialState : function() { return { name : "chris", job : "developer" }; }, render : function() { return <div> My name is {this.state.name} and I am a {this.state.job}. </div>; }});React.renderComponent( <InterfaceComponent />, document.body);
This method tells the component which values should be available from the first render cycle, until the state values are changed. You should never try to use state values without first declaring them in this manner.
這個方法告訴組件什麼樣值可以訪問在第一次的渲染生命週期的時候,直到state發生了改變。
Setting State
Setting state should only be done from inside the component. As mentioned, state should be treated as private data, but there are times when you may need to update it. This is how that is done:
/** * @jsx React.DOM */ var InterfaceComponent = React.createClass({ getInitialState : function() { return { name : "chris" }; }, handleClick : function() { this.setState({ name : "bob" }); }, render : function() { return <div onClick={this.handleClick}> hello {this.state.name} </div>; }});React.renderComponent( <InterfaceComponent />, document.body);
You cannot set new state values until the component has been mounted. This happens when it’s passed (whether directly or by nesting it) to theReact.renderComponent() method. Then again, why would you need to?
Setting state in this way is only really needed when your component’s rendering and behaviour depends on outside factors. We’ll look at examples of that later on in the series.
Replacing State
It’s also possible to replace values in the state by using the replaceState()method. Let’s look at an example of this:
/** * @jsx React.DOM */ var InterfaceComponent = React.createClass({ getInitialState : function() { return { first : "chris", last : "pitt" }; }, handleClick : function() { this.replaceState({ first : "bob" }); }, render : function() { return <div onClick={this.handleClick}> hello { this.state.first + " " + this.state.last } </div>; }});
The replaceState() method is for when you want to clear out the values already in state, and add new ones.
replaceState()方法是在你想清除所有state中的值並且想添加一個的時候使用。
Avoiding State
The use of state should be as limited as it can get. When you use state, you run the risk of introducing a number of (sometimes subtle) errors in the behaviour and rendering of your components.
If you decide to use properties to define your initial state; your properties might change, leaving your initial state calculations based on stale data. You also introduce tight coupling between the properties that need to be defined, and the internal state of the component.
A general rule is not to use state for static components. If you component does not need to change, based on external factors, then do not use state. It’s better to calculate rendered values in the render() method.
Conclusion
State is a double-edged sword. On the one hand, it’s useful for sanely controlling internal data. On the other, it can lead to all sorts of mayhem, if not properly controlled. Use it wisely!
state是一把雙刃劍,你最好把state當作私人資料來使用。
React State學習