React/Redux/ImmutableJS get() returns 未定义
React/Redux/ImmutableJS get() returns undefined
我正在尝试更新我的 redux 存储,在 api 调用之后,通过将负载与 Map() 的初始状态合并。我可以在 mapStateToProps 中使用点表示法访问状态属性,但是在尝试调用 state.get('prop') 时,该值未定义。
actions.js
export function loadPackages() {
return function(dispatch) {
return PackageApi.getAllPackages().then(packages => {
dispatch(loadPackagesSuccess(packages));
}).catch(error => {
throw(error);
});
};
}
export function loadPackagesSuccess(packages) {
return {
type: 'LOAD_PACKAGES_SUCCESS',
packages
}
}
reducer.js
const reducer = (state = Map(), action) => {
switch (action.type) {
case 'LOAD_PACKAGES_SUCCESS':
return update(state, {$merge: action.packages});
default:
return state;
}
}
export default reducer;
Packages.jsx
const mapStateToProps = (state) => {
console.log(state.results); // (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
return {
state,
packages: state.get('results') // undefined
};
}
编辑
reducer.js
const initialState = Map({
packages: {
totalCount: null,
results: List(),
dir: null,
totalPages: null,
limit: null,
sort: null,
page: null
}
});
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'LOAD_PACKAGES_SUCCESS':
return state.set('packages', fromJS(action.packages));
default:
return state;
}
}
Packages.jsx
export class Packages extends React.Component {
componentDidMount() {
this.props.dispatch(loadPackages(this.props.state));
}
render() {
return (
<div className="col-lg-12">
{this.props.results ?
<PackageList allPackages={this.props.results} /> :
<h3>No Packages Available</h3>}
</div>
);
}
};
const mapStateToProps = (state) => {
console.log(state.getIn(['packages','results']));
/* Doesn't print the actual value of results but shows the
immutable structure: List {size: 10, _origin: 0, _capacity: 10,
_level: 5, _root: null, …} */
return {
packages: state.get('packages'),
results: state.getIn(['packages','results'])
};
}
PackageList.jsx
const PackageList = ({allPackages}) => {
const packageItems = allPackages.map(pkg =>
<li key={pkg.get('id')}>{pkg.get('packageName')}</li>
);
return (
<ul className="packages">
{packageItems}
</ul>
);
};
如果 state 中的结构错误,则说明你的 reducer 有问题。
替换为:return update(state, {$merge: action.packages});
有了这个:return state.set('packages', Immutable.fromJs(action.packages));
现在您使用来自 https://reactjs.org/docs/update.html 的 vanilla js 不可变数据突变助手,其中 returns 新基础 JS objects/arrays 等,并且与 Immutable.Js 库无关,您尝试在裸 JS 对象上使用 Immutable.js 方法。
我正在尝试更新我的 redux 存储,在 api 调用之后,通过将负载与 Map() 的初始状态合并。我可以在 mapStateToProps 中使用点表示法访问状态属性,但是在尝试调用 state.get('prop') 时,该值未定义。
actions.js
export function loadPackages() {
return function(dispatch) {
return PackageApi.getAllPackages().then(packages => {
dispatch(loadPackagesSuccess(packages));
}).catch(error => {
throw(error);
});
};
}
export function loadPackagesSuccess(packages) {
return {
type: 'LOAD_PACKAGES_SUCCESS',
packages
}
}
reducer.js
const reducer = (state = Map(), action) => {
switch (action.type) {
case 'LOAD_PACKAGES_SUCCESS':
return update(state, {$merge: action.packages});
default:
return state;
}
}
export default reducer;
Packages.jsx
const mapStateToProps = (state) => {
console.log(state.results); // (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
return {
state,
packages: state.get('results') // undefined
};
}
编辑
reducer.js
const initialState = Map({
packages: {
totalCount: null,
results: List(),
dir: null,
totalPages: null,
limit: null,
sort: null,
page: null
}
});
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'LOAD_PACKAGES_SUCCESS':
return state.set('packages', fromJS(action.packages));
default:
return state;
}
}
Packages.jsx
export class Packages extends React.Component {
componentDidMount() {
this.props.dispatch(loadPackages(this.props.state));
}
render() {
return (
<div className="col-lg-12">
{this.props.results ?
<PackageList allPackages={this.props.results} /> :
<h3>No Packages Available</h3>}
</div>
);
}
};
const mapStateToProps = (state) => {
console.log(state.getIn(['packages','results']));
/* Doesn't print the actual value of results but shows the
immutable structure: List {size: 10, _origin: 0, _capacity: 10,
_level: 5, _root: null, …} */
return {
packages: state.get('packages'),
results: state.getIn(['packages','results'])
};
}
PackageList.jsx
const PackageList = ({allPackages}) => {
const packageItems = allPackages.map(pkg =>
<li key={pkg.get('id')}>{pkg.get('packageName')}</li>
);
return (
<ul className="packages">
{packageItems}
</ul>
);
};
如果 state 中的结构错误,则说明你的 reducer 有问题。
替换为:return update(state, {$merge: action.packages});
有了这个:return state.set('packages', Immutable.fromJs(action.packages));
现在您使用来自 https://reactjs.org/docs/update.html 的 vanilla js 不可变数据突变助手,其中 returns 新基础 JS objects/arrays 等,并且与 Immutable.Js 库无关,您尝试在裸 JS 对象上使用 Immutable.js 方法。