【发布时间】:2018-01-25 00:08:22
【问题描述】:
我正在更新我的第一个 react/redux 应用程序以使用 redux-immutable 并且无法弄清楚为什么 mapStateToProps 中的道具是空的。我看到 thunk 记录器输出中填充了属性,但它们在组件中为空。
components/Packages.jsx:
import React from 'react';
import pureRender from 'pure-render-decorator';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {loadPackages} from '../../actions/packageActions';
import PackageList from './PackageList';
import ImmutablePropTypes from 'react-immutable-proptypes';
import {Map,fromJS,List} from 'immutable';
export class Packages extends React.Component {
constructor(props, context) {
super(props, context);
}
componentDidMount() {
this.props.dispatch(loadPackages());
}
render() {
return (
<div className="col-lg-12">
{this.props.results.length ?
<PackageList results={this.props.results} /> :
<h3>No Packages Available</h3>}
</div>
);
}
};
Packages.propTypes = {
results: ImmutablePropTypes.list.isRequired,
};
const mapStateToProps = (state, ownProps) => {
return {
packages: state.get('packages'),
results: !state.getIn(['packages','results']) ? List() : state.getIn(['packages','results'])
};
}
export const PackagesContainer = connect(mapStateToProps)(Packages);
actions/packageActions.jsx:
import * as types from './actionTypes';
import PackageApi from '../api/packageApi';
export function loadPackages() {
return function(dispatch) {
return PackageApi.getAllPackages().then(packages => {
dispatch(loadPackagesSuccess(packages));
}).catch(error => {
throw(error);
});
};
}
export function loadPackagesSuccess(packages) {
return {
type: types.LOAD_PACKAGES_SUCCESS,
state: packages.data
}
}
reducers/packageReducer.js:
import {Map,fromJS,List} from 'immutable';
import * as types from '../actions/actionTypes';
import initialState from './initialState';
export default function packageReducer(state = initialState, action) {
switch (action.type) {
case types.LOAD_PACKAGES_SUCCESS:
return state.set('packages', fromJS(action.state));
default:
return state;
}
}
reducers/initialState.js:
import {Map, List} from 'immutable';
import update from 'immutability-helper';
const initialState = Map({
packages: Map({
totalCount: null,
results: List(),
dir: null,
totalPages: null,
limit: null,
sort: null,
page: null
})
});
export default initialState;
reducers/rootReducer.js:
import {combineReducers} from 'redux-immutable';
import packages from './packageReducer';
import login from './loginReducer';
import { reducer as form } from 'redux-form/immutable';
const reducer = combineReducers({
packages,
login,
form
});
export default reducer;
store.js:
import {createStore, applyMiddleware} from 'redux';
import {createLogger} from 'redux-logger';
import reducer from './reducers/rootReducer';
import thunk from 'redux-thunk';
import initialState from './reducers/initialState';
const store = createStore(reducer, initialState, applyMiddleware(thunk, createLogger()));
export default store;
thunk log:
state:{
results: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
type: "LOAD_PACKAGES_SUCCESS"
}
编辑
Redux DevTools 显示正确的数据结构,但 mapStateToProps 仍然返回空列表。
Redux 开发工具:
{
packages
packages{
"totalCount": 145,
"results": [
{
Packages.jsx:
const mapStateToProps = (state, ownProps) => {
return {
packages: state.get('packages'),
results: !state.getIn(['packages','packages','results']) ? List() : state.getIn(['packages','packages','results'])
};
}
我更新了initialState,它解决了state.getIn(['packages','results']); 是undefined 的问题。但是,结果属性仍然会生成一个空列表。
【问题讨论】:
-
您是否检查以确保
LOAD_PACKAGES_SUCCESS操作正确更新了商店?Packages组件是否从默认(未命名)导出中导入,以确保它包含在connect中? -
如何验证 LOAD_PACKAGES_SUCCESS 操作是否正确更新了商店? PackagesContainer 在 index.jsx 中被导入为
import {PackagesContainer} from './components/Package/Packages'; -
您可以使用 Chrome 的 Redux DevTools 扩展程序来查看您的 Redux 存储在所有调度操作之前和之后的状态。
-
您必须将组合减速器(即“packages”名称)传递给 state.get,例如 packages:state.get(“packages”, “packages”);在你的 mapStateToProps 中。这里 state.get 的第一个参数是您在组合减速器中定义的包名称,第二个参数是您在包减速器中设置的。您必须像这样传递才能获取组件中的数据。
标签: reactjs redux redux-immutable