Reactjs,父组件,状态和道具
Reactjs, parent component, state and props
我实际上正在学习 reactjs,我实际上正在开发一个小的 TODO 列表,包裹在一个名为 TODO 的 "parent component" 中。
在此父级内部,我想从相关商店获取 TODO 的当前状态,然后将此状态作为 属性 传递给子组件。
问题是我不知道在哪里初始化我的父状态值。
事实上,我使用的是 ES6 语法,所以我没有 getInitialState() 函数。文档中写到我应该使用组件构造函数来初始化这些状态值。
事实是,如果我想在我的构造函数中初始化状态,this.context(Fluxible Context)实际上是未定义的。
我决定将初始化移动到 componentDidMount 内部,但这似乎是一种反模式,我需要另一种解决方案。你能帮帮我吗?
这是我的实际代码:
import React from 'react';
import TodoTable from './TodoTable';
import ListStore from '../stores/ListStore';
class Todo extends React.Component {
constructor(props){
super(props);
this.state = {listItem:[]};
this._onStoreChange = this._onStoreChange.bind(this);
}
static contextTypes = {
executeAction: React.PropTypes.func.isRequired,
getStore: React.PropTypes.func.isRequired
};
componentDidMount() {
this.setState(this.getStoreState()); // this is what I need to move inside of the constructor
this.context.getStore(ListStore).addChangeListener(this._onStoreChange);
}
componentWillUnmount() {
this.context.getStore(ListStore).removeChangeListener(this._onStoreChange);
}
_onStoreChange () {
this.setState(this.getStoreState());
}
getStoreState() {
return {
listItem: this.context.getStore(ListStore).getItems() // gives undefined
}
}
add(e){
this.context.executeAction(function (actionContext, payload, done) {
actionContext.dispatch('ADD_ITEM', {name:'toto', key:new Date().getTime()});
});
}
render() {
return (
<div>
<button className='waves-effect waves-light btn' onClick={this.add.bind(this)}>Add</button>
<TodoTable listItems={this.state.listItem}></TodoTable>
</div>
);
}
}
export default Todo;
作为 Fluxible 用户,您应该受益于 Fluxible addons:
以下示例将监听 FooStore 和 BarStore 中的变化,并在实例化时将 foo 和 bar 作为 props 传递给组件。
class Component extends React.Component {
render() {
return (
<ul>
<li>{this.props.foo}</li>
<li>{this.props.bar}</li>
</ul>
);
}
}
Component = connectToStores(Component, [FooStore, BarStore], (context, props) => ({
foo: context.getStore(FooStore).getFoo(),
bar: context.getStore(BarStore).getBar()
}));
export default Component;
查看 fluxible example 了解更多详情。代码摘录:
var connectToStores = require('fluxible-addons-react/connectToStores');
var TodoStore = require('../stores/TodoStore');
...
TodoApp = connectToStores(TodoApp, [TodoStore], function (context, props) {
return {
items: context.getStore(TodoStore).getAll()
};
});
因此您不需要调用 setState,所有存储数据都将在组件的 props 中。
我实际上正在学习 reactjs,我实际上正在开发一个小的 TODO 列表,包裹在一个名为 TODO 的 "parent component" 中。
在此父级内部,我想从相关商店获取 TODO 的当前状态,然后将此状态作为 属性 传递给子组件。
问题是我不知道在哪里初始化我的父状态值。
事实上,我使用的是 ES6 语法,所以我没有 getInitialState() 函数。文档中写到我应该使用组件构造函数来初始化这些状态值。
事实是,如果我想在我的构造函数中初始化状态,this.context(Fluxible Context)实际上是未定义的。
我决定将初始化移动到 componentDidMount 内部,但这似乎是一种反模式,我需要另一种解决方案。你能帮帮我吗?
这是我的实际代码:
import React from 'react';
import TodoTable from './TodoTable';
import ListStore from '../stores/ListStore';
class Todo extends React.Component {
constructor(props){
super(props);
this.state = {listItem:[]};
this._onStoreChange = this._onStoreChange.bind(this);
}
static contextTypes = {
executeAction: React.PropTypes.func.isRequired,
getStore: React.PropTypes.func.isRequired
};
componentDidMount() {
this.setState(this.getStoreState()); // this is what I need to move inside of the constructor
this.context.getStore(ListStore).addChangeListener(this._onStoreChange);
}
componentWillUnmount() {
this.context.getStore(ListStore).removeChangeListener(this._onStoreChange);
}
_onStoreChange () {
this.setState(this.getStoreState());
}
getStoreState() {
return {
listItem: this.context.getStore(ListStore).getItems() // gives undefined
}
}
add(e){
this.context.executeAction(function (actionContext, payload, done) {
actionContext.dispatch('ADD_ITEM', {name:'toto', key:new Date().getTime()});
});
}
render() {
return (
<div>
<button className='waves-effect waves-light btn' onClick={this.add.bind(this)}>Add</button>
<TodoTable listItems={this.state.listItem}></TodoTable>
</div>
);
}
}
export default Todo;
作为 Fluxible 用户,您应该受益于 Fluxible addons:
以下示例将监听 FooStore 和 BarStore 中的变化,并在实例化时将 foo 和 bar 作为 props 传递给组件。
class Component extends React.Component {
render() {
return (
<ul>
<li>{this.props.foo}</li>
<li>{this.props.bar}</li>
</ul>
);
}
}
Component = connectToStores(Component, [FooStore, BarStore], (context, props) => ({
foo: context.getStore(FooStore).getFoo(),
bar: context.getStore(BarStore).getBar()
}));
export default Component;
查看 fluxible example 了解更多详情。代码摘录:
var connectToStores = require('fluxible-addons-react/connectToStores');
var TodoStore = require('../stores/TodoStore');
...
TodoApp = connectToStores(TodoApp, [TodoStore], function (context, props) {
return {
items: context.getStore(TodoStore).getAll()
};
});
因此您不需要调用 setState,所有存储数据都将在组件的 props 中。