Reputation: 33668
Any react component I can imagine that uses state can be rewritten to use props. For example:
var Hello = React.createClass({
getInitialState: function () {
return {name: 'World'};
},
render: function() {
return <div>Hello {this.state.name}</div>;
}
});
var name = 'World';
var element = React.render(<Hello />, document.getElementById('container'));
function toggle_name() {
name = (name == 'World') ? 'Universe' : 'World';
element.setState({name: name});
}
If this would be inside another Component, you would write it with props anyway. But the same is possible with the outermost component:
var Hello = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
var name = 'World';
React.render(<Hello name={name} />, document.getElementById('container'));
function toggle_name()
{
name = (name == 'World') ? 'Universe' : 'World';
React.render(<Hello name={name} />, document.getElementById('container'));
}
So when should I use state then?
My variable name
certainly has the role of state, that's why I wonder what I'd gain from using React's state system.
Upvotes: 3
Views: 423
Reputation: 19998
state
is your source of truth. If your source of truth is external to a component accept props
. If your component determines it's own truth and modifies it over time use state
. If two components require the same truth, find a common parent and store it there.
It's possible to pull all your state
up to the outermost component, leaving all child components to use props
only. You can even, as you say, pull all state
out of all components so all components accept only props
.
What you are doing is maximising state impact potential whereas you want to minimise it. Minimising the impact state improves how easily you can reason about your rendering.
For each piece of state in your application: (1) Identify every component that renders something based on that state. (2) Find a common owner component (a single component above all the components that need the state in the hierarchy).
Put state as close as you can to the components that are impacted by it:
var Parent = React.createClass({
getInitialState: function() {
return {stateParentAndChildCaresAbout: "someVariable"};
},
render: function() {
return <Child tellMeWhatToDo={this.state.stateParentAndChildCaresAbout} />
}
});
var Child = React.createClass({
getInitialState: function() {
return {stateOnlyChildCaresAbout: "someVariable"};
},
render: function() {
return <span>{this.state.stateOnlyChildCaresAbout} {this.props.tellMeWhatToDo}</span>;
}
});
Upvotes: 1
Reputation: 28158
For parent-child communication, simply pass props.
Use state to store the data your current page needs in your controller-view.
Use props to pass data & event handlers down to your child components.
These lists should help guide you when working with data in your components.
Props
State
For communication between two components that don't have a parent-child relationship, you can set up your own global event system. Subscribe to events in componentDidMount(), unsubscribe in componentWillUnmount(), and call setState() when you receive an event. Flux pattern is one of the possible ways to arrange this. - https://facebook.github.io/react/tips/communicate-between-components.html
What Components Should Have State?
Most of your components should simply take some data from props and render it. However, sometimes you need to respond to user input, a server request or the passage of time. For this you use state.
Try to keep as many of your components as possible stateless. By doing this you'll isolate the state to its most logical place and minimize redundancy, making it easier to reason about your application.
A common pattern is to create several stateless components that just render data, and have a stateful component above them in the hierarchy that passes its state to its children via props. The stateful component encapsulates all of the interaction logic, while the stateless components take care of rendering data in a declarative way. - https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-components-should-have-state
What Should Go in State?
State should contain data that a component's event handlers may change to trigger a UI update. In real apps this data tends to be very small and JSON-serializable. When building a stateful component, think about the minimal possible representation of its state, and only store those properties in this.state. Inside of render() simply compute any other information you need based on this state. You'll find that thinking about and writing applications in this way tends to lead to the most correct application, since adding redundant or computed values to state means that you need to explicitly keep them in sync rather than rely on React computing them for you. - https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-should-go-in-state
Upvotes: 2