发生了一些奇怪的事情,我一直在阅读React文档,他们谈论生命周期以及如何在渲染组件之前做一些事情。我正在尝试,但我尝试的一切都失败了,总是组件首先进行渲染,然后调用componenWillMount,.. diMount等等。在调用这些函数之后,渲染再次发生。
我需要首先加载数据以填充状态,因为我不希望初始状态为null
,我希望它与初始渲染后的数据一样。
我正在使用Flux和Alt,这是
动作
@createActions(flux)
class GetDealersActions {
constructor () {
this.generateActions('dealerDataSuccess', 'dealerDataFail');
}
getDealers (data) {
const that = this;
that.dispatch();
axios.get(`${API_ENDPOINT}/get-dealers/get-dealers`)
.then(function success (response) {
console.log('success GetDealersActions');
that.actions.dealerDataSuccess({...response.data});
})
}
}
然后商店
@createStore(flux)
class GetDealersStore {
constructor () {
this.state = {
dealerData : null,
};
}
@bind(GetDealersActions.dealerDataSuccess)
dealerDataSuccess (data) {
this.setState({
dealerData : data,
});
}
}
和组件
@connectToStores
export default class Dealers extends Component {
static propTypes = {
title : React.PropTypes.func,
}
static contextTypes = {
router : React.PropTypes.func,
}
constructor (props) {
super(props);
this.state = {
modal : false,
dealerData : this.props.dealerData,
}
}
componentWillMount () {
GetDealersActions.getDealers();
this.setState({
dealerData : this.props.dealerData.dealersData,
})
}
static getStores () {
return [ GetDealersStore ];
}
static getPropsFromStores () {
return {
...GetDealersStore.getState(),
}
}
render () {
return (<div>
<div style={Styles.mainCont}>
{!!this.props.dealerData ?
this.props.dealerData.dealersData.map((dealer) => {
return (<div>HERE I AM RENDERING WHAT I NEED</div>);
}) : <p>Loading . . .</p>
}
</div>
</div>
);
}
}
正如您在组件部分中看到的那样,我有这个
constructor (props) {
super(props);
this.state = {
modal : false,
dealerData : this.props.dealerData,
}
}
componentWillMount () {
GetDealersActions.getDealers();
this.setState({
dealerData : this.props.dealerData.dealersData,
})
}
告诉我dealerData is undefined
或can not read property of null
。
我需要的只是知道一种技术,我可以在初始渲染发生之前获取数据。所以我可以填写state
并开始处理这些数据。
答案 0 :(得分:4)
React确保componentWillMount
中的状态分配将在第一次渲染之前进行。正如你在评论中所说:
在初始渲染发生之前,在客户端和服务器上调用一次。如果在此方法中调用setState,则render()将看到更新的状态,并且只会在状态更改时执行一次。
但是,请求的异步操作不会立即更新您的商店。调用GetDealersActions.getDealers();
将发出使用新内容更新商店的情况,但响应将仅在事件队列中稍后到达。这意味着this.props.dealersData
在函数期间不会更改,setState
将尝试读取未定义属性的属性“dealersData”。无论如何,在第一次渲染时无法看到请求的内容。
我的建议与similar question中的建议相同。防止组件呈现该内容,直到它变得可用为止,正如您所做的那样,在程序中是一件合适的事情。或者,在“dealersData”尚未到达的情况下渲染装载程序。
要解决您的特定问题,请从setState
删除componentWillMount
。如果您的父组件正在正确地监听更改并将它们传播到子项的道具,那么所有这些都应该可以正常工作。
componentWillMount () {
GetDealersActions.getDealers();
}
答案 1 :(得分:1)
我用来从服务器接收数据并显示它的最佳答案
constructor(props){
super(props);
this.state = {
items2 : [{}],
isLoading: true
}
}
componentWillMount (){
axios({
method: 'get',
responseType: 'json',
url: '....',
})
.then(response => {
self.setState({
items2: response ,
isLoading: false
});
console.log("Asmaa Almadhoun *** : " + self.state.items2);
})
.catch(error => {
console.log("Error *** : " + error);
});
})}
render() {
return(
{ this.state.isLoading &&
<i className="fa fa-spinner fa-spin"></i>
}
{ !this.state.isLoading &&
//external component passing Server data to its classes
<TestDynamic items={this.state.items2}/>
}
) }