我正在使用React,我正在努力了解生命周期。我正在做一个componentWillMount
方法,以便在渲染发生之前获得我需要的props
。我需要知道在加载视图时如何更新状态。
我要做的只是GET
请求,以获取赌场游戏的经销商列表。基本上,我缺少1或2个步骤来渲染经销商在DOM中的列表
我将展示我在使用我的代码做什么,之后我将解释我想要的内容
行动部分
getDealerActions.js
class GetDealersActions {
constructor () {
this.generateActions('dealerDataSuccess', 'dealerDataFail');
}
getDealers (data) {
const that = this;
that.dispatch();
axios.get('someroute/get-dealers/get-dealers')
.then(function success (response) {
that.actions.dealerDataSuccess({...response.data});
})
}
};
然后我们搬到商店
getDealersStore.js
class GetDealersStore {
constructor () {
this.state = {
dealerData : null,
};
}
@bind(GetDealersActions.dealerDataSuccess)
dealerDataSuccess (data) {
this.setState({
dealerData : data,
});
console.log(this.state.dealerData);
}
}
在这种情况下,console.log(this.state.dealerData);
会返回类似这样的内容,这正是我需要的内容
Object {dealersData: Array[3]}
问题出现在组件部分,老实说,因为我不知道如何处理这里的数据
@connectToStores
export default class Dealers extends Component {
static contextTypes = {
router : React.PropTypes.func,
}
constructor (props) {
super(props);
this.state = {}
}
static getStores () {
return [ GetDealersStore ];
}
static getPropsFromStores () {
return GetDealersStore.getState();
}
componentWillMount () {
console.log('@@@', this.props);
GetDealersActions.getDealers();
}
render () {
console.log('>>>', this.props);
let content;
if (this.state.dealerData) {
content = this.state.dealerData.map((item) => {
return <div key={item.CardId}>{item}</div>;
});
} else {
content = <div>Loading . . .</div>;
}
return (
<div>
<div>{content}</div>
</div>
);
}
}
我到达<div>{content}</div>
的所有内容都是Loading . . .
,因为this.state
就是这样Object {}
我得到的一个奇怪的情况是,这个视图渲染两次,第一次渲染,console.log('>>>', this.props);
返回此>>> Object {params: Object, query: Object}
,第二次渲染,触发此{{} 1}}这就是我需要的。
那么,为什么>>> Object {params: Object, query: Object, dealerData: Object}
正在等待渲染方法才能被触发?
答案 0 :(得分:6)
这根本不奇怪。 componentWillMount
将在渲染之前触发,在第一遍中,您将调用一个操作来获取经销商GetDealersActions.getDealers();
,这基本上是异步命令。由于它是异步的,因此组件在获取数据之前将呈现一次,然后在商店发布changed
事件之后再次呈现,这将重新触发呈现。
以下是示例中发生的动作序列的近似值:
componentWillMount
调用getDealers
命令(异步)render
,默认组件状态dealer
数据changed
事件,重新触发呈现render
数据调用第二个dealer
。问题是React会以某种顺序运行它的生命周期方法,而不是关心你调用一些异步方法。所以基本上你没有办法停止rendering
因为你调用了一个命令来获取dealers
。这是react
(或一个特性)的限制,当与异步编程结合使用时会出现,你应该按原样接受它。
如果您接受React将渲染两次的事实,您可以利用它对您有利,所以首先渲染您可以只显示loading
指示符(例如旋转轮),当数据加载时将其显示在第二个render
。
但是,如果您不相信并且仍然希望避免在初始加载中进行双重渲染,则可以在安装应用程序组件之前预取数据,这样可以确保在存储之前将初始数据加载到存储中。第一个render
,这意味着您不必在getDealers
中调用componentWillMount
,因为数据已经存储在第一个render
的商店中。
提醒一下,双重渲染不是一个重要的性能问题,就像它在Angular.js或Ember.js中一样,因为React在DOM操作方面非常有效,但如果处理不当,它可能会产生一些UX问题