用react和redux显示json数据

时间:2016-08-26 01:32:26

标签: json reactjs redux

我正在尝试使用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

2 个答案:

答案 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秒后加载标题。

希望能帮助您完成反应/减少旅程。