我正在使用 React 和 Redux 构建应用程序。
我有一个 Account 组件,它从componentWillMount
方法中的服务器获取数据。在获取数据时,组件必须显示“正在加载”文本,因此我已将“isFetching”属性添加到帐户缩减程序中。从服务器获取数据时,此属性设置为 true。
问题是,在获取数据时,该render
方法中“isFetching”属性的值为 false,而同时 的值为store.getState().account.isFetching
true(必须如此)。这导致例外,因为this.props.isFetching
是假的,那么代码是试图展示this.props.data.protectedString
,而data
仍然被从服务器加载(所以它为空)。
我假设 mapStateToProps 绑定了一些错误的值(可能是初始状态),但我不知道为什么以及如何修复它。
这是我的 AccountView 代码:
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actionCreators from '../../actions/account';
class AccountView extends React.Component {
componentWillMount() {
const token = this.props.token;
// fetching the data using credentials
this.props.actions.accountFetchData(token);
}
render() {
console.log("store state", window.store.getState().account); // isFetching == true
console.log("componentState", window.componentState); // isFetching == false
return (
<div>
{this.props.isFetching === true ? <h3>LOADING</h3> : <div>{this.props.data.protectedString}</div> }
</div>
);
}
}
const mapStateToProps = (state) => {
window.componentState = state.account;
return {
data: state.account.data,
isFetching: state.account.isFetching
};
};
const mapDispatchToProps = (dispatch) => {
return {
actions: bindActionCreators(actionCreators, dispatch)
};
};
export default connect(mapStateToProps, mapDispatchToProps)(AccountView);
帐户减少器:
const initialState = {
data: null,
isFetching: false
};
export default function(state = initialState, action) {
switch (action.type) {
case ACCOUNT_FETCH_DATA_REQUEST:
return Object.assign({}, state, {
isFetching: true
});
case ACCOUNT_RECEIVE_DATA:
return Object.assign({}, state, {
data: action.payload.data,
isFetching: false
});
default:
return state;
}
}
行动:
export function accountReceiveData(data) {
return {
type: ACCOUNT_RECEIVE_DATA,
payload: {
data
}
};
}
export function accountFetchDataRequest() {
return {
type: ACCOUNT_FETCH_DATA_REQUEST
};
}
export function accountFetchData(token) {
return (dispatch, state) => {
dispatch(accountFetchDataRequest());
axios({
// axios parameters to fetch data from the server
})
.then(checkHttpStatus)
.then((response) => {
dispatch(accountReceiveData(response.data));
})
.catch((error) => {
//error handling
});
};
}
这就是我创建商店的方式:
import { applyMiddleware, compose, createStore } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import rootReducer from '../reducers';
export default function configureStore(initialState, history) {
// Add so dispatched route actions to the history
const reduxRouterMiddleware = routerMiddleware(history);
const middleware = applyMiddleware(thunk, reduxRouterMiddleware);
const createStoreWithMiddleware = compose(
middleware
);
return createStoreWithMiddleware(createStore)(rootReducer, initialState);
}
在 index.js 中:
import { createBrowserHistory } from 'history';
import { syncHistoryWithStore } from 'react-router-redux';
import configureStore from './store/configureStore';
const initialState = {};
const newBrowserHistory = createBrowserHistory();
const store = configureStore(initialState, newBrowserHistory);
const history = syncHistoryWithStore(newBrowserHistory, store);
// for test purposes
window.store = store;
我的代码基于这个例子 - https://github.com/joshgeller/react-redux-jwt-auth-example
代码看起来相同,但由于某些module的新版本,我更改了一些地方。