假设我有一个如下所示的redux模块:
import fetch from 'isomorphic-fetch';
// CONSTANTS
const LOAD = 'LOAD';
const LOAD_SUCCESS = 'LOAD_SUCCESS';
// REDUCER
const initialState = { loading: false, data: [] };
export default function reducer(state = initialState, action) {
switch (action.type) {
case LOAD: return { ...state, loading: true };
case LOAD_SUCCESS: return { ...state, loading: false, data: action.data };
default: return state;
}
}
// ACTION CREATORS
function requestLocations() {
return { type: LOAD };
}
function receiveLocations(json) {
return { type: LOAD_SUCCESS, data: json };
}
export function fetchLocations() {
return function (dispatch) {
dispatch(requestLocations());
return fetch('http://myurl')
.then(response => response.json())
.then(json => dispatch(receiveLocations(json)));
};
}
如果我在componentWillMount中进行异步调用,我会在第一次渲染时遇到loading
状态。想象一下,我的组件看起来像这样(简化为简洁):
export default class LocationContainer extends React.Component {
componentWillMount() {
fetchLocations(); // already bound and injected via connect.
}
render() {
const { loading, data } = this.props; // injected via connect from reducer above.
if (loading) {
return <Spinner />;
} else {
return <LocationExplorer locations={ data } />;
}
}
}
我遇到的问题是,在第一次呈现LocationContainer
时,loading
为false,而data
尚未提取。在componentWillMount
中,LOAD
操作被触发,并且设置为true的loading
的道具更改排队等待后续渲染。与此同时,在我第一次渲染时,LocationExplorer
会在我真正想要Spinner
时呈现,因为loading
仍然是假的。我想知道如何在不设置firstRender = true
状态变量hack的情况下解决这个问题。
答案 0 :(得分:6)
一个选项可能是使用loading
初始状态扩展您的data
条件:
const initialState = { loading: false, data: [] };
如果您loading
且data
为空,则表示您处于等待新数据到达的确切状态:
if (loading && data.length === 0) {
return <Spinner />;
} else {
另外,我通常将异步调用放在componentDidMount
而不是componentWillMount
。
答案 1 :(得分:0)
请勿在{{1}}中提出请求。相反,在安装组件之前执行此操作。 e.g。
componentWillMount
答案 2 :(得分:0)
除了可接受的答案外,我们一直在使用的另一种获得巨大成功的解决方案是在reducer上添加一个complete
布尔值标志,如果响应在某个时候返回,我们将其标记为true。如果响应实际上返回一个空数组,这会使事情更加明确。 complete
标志让我知道响应是来自服务器的,而不仅仅是我的初始状态。
if(loading && !complete) {
return <Spinner />;
} else {
return <Component data={data} />;
}
我认为我会添加它,以防对他人有所帮助。