假设我有一个如下所示的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)));
};
}
Run Code Online (Sandbox Code Playgroud)
loading如果我在componentWillMount中进行异步调用,我就会在第一次渲染时遇到状态.想象一下,我的组件看起来像这样(简化为简洁):
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 } />;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,在第一次渲染时LocationContainer,loading是假的,data还没有被提取.在componentWillMount,LOAD操作被触发,loading并且设置为true 的道具更改排队等待在后续渲染中发生.与此同时,在我第一次渲染时,LocationExplorer会在我真正想要的时候渲染,Spinner因为loading它仍然是假的.我想知道如何处理这个问题而不设置firstRender = true状态变量hack.
一个选项可能是loading使用您的data初始状态扩展您的条件:
const initialState = { loading: false, data: [] };
Run Code Online (Sandbox Code Playgroud)
如果您loading和您data的空白,则意味着您处于等待新数据到来的确切状态:
if (loading && data.length === 0) {
return <Spinner />;
} else {
Run Code Online (Sandbox Code Playgroud)
此外,我通常把我的异步调用componentDidMount而不是componentWillMount.