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