React并不指示您如何管理数据。如果您使用的getter/setter方法的对象,那么它可能是简单的对整个对象存储在状态:
changeName() {
this.person.setName("Jane");
this.person.setAge(22);
this.setState({person: this.person});
}
通过这种方式,你的对象仍然是负责数据,和任何内部处理这意味着,而结果对象本身存储在组件状态。
也就是说,使用像Person这样的数据对象,虽然可能,但不是惯用的React。我会推荐使用类似Redux的东西,并设置单向数据流。这意味着创建一个Reducer来管理你的状态,并使用动作创建者与Redux商店进行通信。
您可以在reducer中初始化对象的默认值。这是从Redux商店默认返回的。
您的Reducer会侦听UPDATE_PERSON操作,该操作会为整个更新的Person对象带来有效负载。这将如下保存在状态:
减速器/ person.js
const UPDATE_PERSON = 'UPDATE_PERSON';
const initialState = {
name: "Tim",
age: 23
}
const personReducer(state = initialState, action) {
switch (action.type) {
case UPDATE_PERSON:
return {
...state,
name: action.payload.name,
age: action.payload.name
}
default:
return state;
}
}
你行动的创建者是一个简单的功能与type
财产和某种有效载荷:
(据推测)行动/人。JS
export const updatePerson(data) {
return {
type: UPDATE_PERSON,
payload: data
}
}
你那么终极版商店连接到您的组件,并用行动创造者的行动派遣到商店:
import { connect } from 'react-redux';
import * as PersonActionCreators from '../actions/person';
class App extends Component {
changeName() {
this.props.updatePerson({name: "Jane", age: 22});
}
render() {
return (
<div>
<div>Your name is: {this.props.person.name}</div>
<div>Your age is: {this.props.person.age}</div>
<div><button onClick={this.changeName.bind(this)}>Change Name</button></div>
</div>
)
}
}
const mapStateToProps = (state) => ({
person: state.person
});
const mapDispatchToProps = {
updatePerson: PersonActionCreators.updatePerson
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
上面的代码假设你在有一个根减速以下格式:
import { combineReducers } from 'redux';
import personReducer from './reducers/person';
const appReducer = combineReducers({
person: personReducer
})
const rootReducer = (state, action) => appReducer(state, action);
export default rootReducer;
您将需要创建存储并将其连接到您的根减速器。详情可以在here找到。
的combineReducers功能只是帮助构建根减速器:
的combineReducers辅助功能将一个对象,其值是 不同减少功能集成在单一减小功能可以 通行证createStore。
这是更多的样板,但它是在React中处理应用程序状态的既定和最流行的方式。看起来好像很多东西都是在开始的时候,但是一旦你熟悉了reducer,行动创造者和连接功能,它变得非常简单。
Redux使用uni-directional data-flow,这意味着数据流从顶层组件向下到子组件。有状态的组件保持在最低限度;但是在需要状态的地方,connect函数提供了它。当组件需要修改状态时,它通过动作创建者来完成。 reducer监听动作并相应地更新状态。关于这一主题
见丹·阿布拉莫夫的自由理论家课程的精彩介绍终极版:
为什么不干脆让国家的'person'一部分? – bejado
@bejado,我可以,是这样做的正确方法吗?然后我会调用this.state.person.setName()吗?在状态中有方法似乎是错误的,并且对象可能存在对象属性更新的情况,但未调用setState()。 – user11406
我会让'person'成为不可变的对象。每次您需要更改姓名或年龄时,请创建一个包含更改的新人。然后'setState({person:newPerson})' – bejado