我正在尝试使用redux加载一些本地json数据并在react app中显示。但是我在减速器中得到了pageId is undefined
。
不确定我在这里做错了什么,我认为我传递数据的方式可能有些不对,但对于redux来说我是非常新的,所以我不确定。
数据
const page = [
{"title":"Mollis Condimentum Sem Ridiculus"},
{"title":"Pharetra Tellus Amet Commodo"}
]
export default page;
动作
const getPage = (pageId) => {
const page = { pageId: pageId }
return {
type: 'GET_PAGE_SUCCESS',
payload: page
}
}
export default getPage
减速
import getPage from '../actions/actionCreators'
import pageData from './../data/pageData';
const defaultState = pageData
const pageReducer = (state = defaultState, action) => {
if (action.type = 'GET_PAGE_SUCCESS') {
state.page[action.payload.pageId].title = action.payload
}
return state
}
export default PageReducer
组件
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import getpage from '../../actions/actionCreators'
const mapStateToProps = (state, props) => {
const page = state.page[props.pageId]
return { page }
}
class Page extends Component {
componentDidMount () {
this.props.getpage(this.props.pageId)
}
render() {
return (<div><PageContainer pageId={0} /></div>)
}
}
const PageContainer = connect(mapStateToProps, { getpage })(page)
export default Page
答案 0 :(得分:1)
嘿,我认为你的组件中有一个小错误。当您在组件的道具上设置页面而不是pageId时,您正在执行this.props.pageId
。那么不应该是this.props.getPage(this.props.page.pageId)
而是state.page[action.payload.pageId].title = action.payload
吗?可能是吗?
另外一个小小的注意事项,使用redux的一个重要提示是不要改变状态。在您正在执行的减速器z-index:-1
中,您可能不应该像这样设置状态,而是返回一个名为newState的新对象,该对象与state相同,但标题已更新。在Redux中将对象视为不可变是很重要的。干杯
答案 1 :(得分:1)
我已将您的代码修改为可用的JSFiddle以供参考:https://jsfiddle.net/qodof048/11/
我试着让它尽可能接近你的例子,但是让我解释一下我为使它工作所做的改变(还要注意JSFiddle不使用ES6导入语法)。
1)您的PageContainer构造不正确。最后一个参数应该是对Page组件的引用(而不是'page')。
const PageContainer = connect(mapStateToProps, { getPageSimple, getPageAsync })(PageComponent)
2)您在Page组件中使用了PageContainer,但PageContainer是Page的“包装器”。您在渲染方法中使用PageContainer而不是Page,因此它会加载数据(映射状态和操作)。
ReactDOM.render(
<Provider store={store}>
<div>
<PageContainer pageId="0" async={false} />
<PageContainer pageId="1" async={true} />
</div>
</Provider>,
document.getElementById('root')
);
3)商店混淆了一下。如果我正确理解了您的示例,您希望从pageData数组将页面加载到本地存储中,该数组可能模拟服务器调用。在这种情况下,你的intialState不能是pageData,而是一个空对象。可以把它想象成你要填充的本地数据库。然后调用你的动作getPage获取页面(这里是你的数组)并将它发送到商店,这将把它保存在那里。
const getPageSimple = (pageId) => {
const page = pageDatabase[pageId]; // this call would be to the server
// then you dispatch the page you got into state
return {
type: 'GET_PAGE_SUCCESS',
payload: {
id: pageId,
page: page
}
}
}
4)我已经向JSFiddle添加了一个异步示例来解释如何从服务器实际获取页面(因为简单的示例是不够的)。这需要用于redux的thunk中间件才能工作(因为你需要访问调度方法才能异步调用它)。 setTimeout模拟长时间运行的调用。
const getPageAsync = (pageId)=>{
return (dispatch, getState) => {
setTimeout(()=>{
const page = pageDatabase[pageId]; // this call would be to the server, simulating with a setTimeout
console.log("dispatching");
// then you dispatch the page you got into state
dispatch({
type: 'GET_PAGE_SUCCESS',
payload: {
id: pageId,
page: page
}
});
}, 2000);
}
}
JSFiddle加载2个容器,一个包含简单的getPage,另一个包含异步版本,在2秒后加载标题。
希望能帮助您完成反应/减少旅程。