【问题标题】:Error in mapPropsToState upon clicking react-router Link单击 react-router 链接时 mapPropsToState 出错
【发布时间】:2017-03-30 19:14:53
【问题描述】:

我一直在尝试通过建立一个简单的博客来学习 redux。

一切似乎都很顺利,直到我使用 react-router Link 组件在博客列表页面中使用博客标题导航到博客详细信息页面。

所以,我有以下反应路线:

  1. 根目录 (/)
  2. 显示帖子 (/posts/:id)

如果我通过在浏览器中输入它们来访问每条路线,它就可以正常工作。

但是,问题是当我在根页面时,然后我单击链接转到博客文章详细路径。

这是我的 redux 状态:

import {
  FETCH_POST_LIST_REQUEST,
  FETCH_POST_LIST_SUCCESS,
  FETCH_POST_LIST_ERROR,
  FETCH_POST_REQUEST,
  FETCH_POST_SUCCESS,
  FETCH_POST_ERROR,
  CREATE_POST_REQUEST,
  CREATE_POST_SUCCESS,
  CREATE_POST_ERROR
} from '../constants'

const initialState = {
  postsList: {
    data: { collection: [] },
    isLoading: false
  },
  newPost: {
    data: {},
    isLoading: false
  },
  post: {
    data: {},
    isLoading: false
  }
}

const posts = function(state = initialState, action) {
  switch (action.type) {
  case FETCH_POST_LIST_REQUEST:
    return {
      postsList: { data: { collection: [] }, isLoading: true }
    }
  case FETCH_POST_LIST_SUCCESS:
    return {
      postsList: { data: action.data, isLoading: false }
    }
  case FETCH_POST_LIST_ERROR:
    return {
      postsList: { data: [], isLoading: false }
    }
  case FETCH_POST_REQUEST:
    return {
      post: { data: {}, isLoading: true }
    }
  case FETCH_POST_SUCCESS:
    return {
      post: { data: action.data, isLoading: false }
    }
  case FETCH_POST_ERROR:
    return {
      post: { data: {}, isLoading: false }
    }
  case CREATE_POST_REQUEST:
    return {
      newPost: { data: {}, isLoading: true }
    }
  case CREATE_POST_SUCCESS:
    return {
      newPost: { data: action.data, isLoading: false }
    }
  case CREATE_POST_ERROR:
    return {
      newPost: { data: {}, isLoading: false }
    }
  default:
    return state
  }
}

我也能够弄清楚为什么会出现错误。

当我在根路径时,我的 redux 状态是posts: { postsList: ... }

当我直接进入显示路径时,我的 redux 状态变为posts: { post: ... }

当我单击Link 时,我应该将我路由到/posts/1,并呈现以下容器:

import PostShow from '../components/post-show'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as actionCreators from '../actions'

const mapStateToProps = function(state) {
  return {
    data: state.posts.post.data,
    isLoading: state.posts.post.isLoading
  }
}

const mapDispatchToProps = function(dispatch) {
  return {
    actions: bindActionCreators(actionCreators, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(PostShow)

此容器连接到以下组件:

import React from 'react'

class PostShow extends React.Component {
  componentDidMount() {
    this.props.actions.fetchPost(this.props.id)
  }

  render() {
    return (
      <div>
        {
            this.props.isLoading ?
            'Loading...' :
            (
             <div className="post">
              <p className="title">{this.props.data.title}</p>
              <p className="content">{this.props.data.content}</p>
              <p className="author">{this.props.data.author}</p>
            </div>
            )
        }
      </div>
    )
  }
}

export default PostShow

在从根路径转换到显示路径时,通过单击 react-router 链接,在以下代码中:

const mapStateToProps = function(state) {
  return {
    data: state.posts.post.data,
    isLoading: state.posts.post.isLoading
  }
}

redux状态还是posts: { postsList: ... },而不是posts: { post: ... },导致state.posts.post.data处出错,导致容器抛出错误。

我做事的方式,只有在componentDidMount中触发了store dispatch后才会改变状态:

componentDidMount() {
  this.props.actions.fetchPost(this.props.id)
}

我想我要么做错了事,要么错过了什么。

谁能帮我解决这个问题?

谢谢。

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:

    你必须稍微改变你的减速器,

    const posts = function(state = initialState, action) {
      switch (action.type) {
      case FETCH_POST_LIST_REQUEST:
        return {
          ...state,
          postsList: { data: { collection: [] }, isLoading: true }
        }
      case FETCH_POST_LIST_SUCCESS:
        return {
          ...state,
          postsList: { data: action.data, isLoading: false }
        }
      case FETCH_POST_LIST_ERROR:
        return {
          ...state,
          postsList: { data: [], isLoading: false }
        }
      case FETCH_POST_REQUEST:
        return {
          ...state,
          post: { data: {}, isLoading: true }
        }
      case FETCH_POST_SUCCESS:
        return {
          ...state,
          post: { data: action.data, isLoading: false }
        }
      case FETCH_POST_ERROR:
        return {
          ...state,
          post: { data: {}, isLoading: false }
        }
      case CREATE_POST_REQUEST:
        return {
          ...state,
          newPost: { data: {}, isLoading: true }
        }
      case CREATE_POST_SUCCESS:
        return {
          ...state,
          newPost: { data: action.data, isLoading: false }
        }
      case CREATE_POST_ERROR:
        return {
          ...state,
          newPost: { data: {}, isLoading: false }
        }
      default:
        return state
      }
    }
    

    看看这里:http://redux.js.org/docs/basics/Reducers.html

    【讨论】:

    • 太棒了!非常感谢!我错过了 Redux 的一个非常基本的原则,并修改了状态树。我这样做的方式是拉出键“post”,“newPost”。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-30
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多