【问题标题】:Unable to access Redux state in React component无法访问 React 组件中的 Redux 状态
【发布时间】:2018-01-24 08:19:17
【问题描述】:

我正在尝试将 redux 状态显示到我的 react 组件中。我的根 reducer 看起来是这样的:

index.js

import { combineReducers } from 'redux';
import PostReducer from './PostsReducer';
import { reducer as formReducer} from 'redux-form';
import CategoriesReducer from './CategoriesReducer';
import CommentsReducer from './CommentsReducer';

const rootReducer = combineReducers({
    posts: PostReducer,
    categories: CategoriesReducer,
    comments: CommentsReducer,
    form : formReducer
});

export default rootReducer;

现在,我在访问我的 cmets 状态时遇到问题。我的 CommentsReducer 减速器如下所示:

CommentsReducer.js

import { FETCH_COMMENTS } from '../actions/comment_action';

export default function(state={}, action) {
    switch (action.type) {
      case FETCH_COMMENTS:
          return {comments: {...state.comments, ...action.payload.data}};

      default:
        return state;
    }
}

在我的组件中,我试图在我的 mapStateToProps 方法中获取 state,如下所示:

function mapStateToProps({ posts, comments }, ownProps) {
    return {
      post: posts[ownProps.match.params.id],
      comment: comments[ownProps.match.params.id]};
}

现在,在我的渲染函数中,如果我尝试将 cmets 状态设置为 {this.props.cmets} ,我收到 null。我的意思是它不显示任何内容。我该如何继续?

编辑 1: 添加状态截图:

EDIT 2条件渲染:

{
            (createStoreWithMiddleware.getState().comments) ?

              <div>
                  {this.props.comment}
              </div>
                                                  :
              <div>
                Null
              </div>

          }

EDIT 3:API 服务器中的 Comment.js 文件。

const defaultData = {
  "894tuq4ut84ut8v4t8wun89g": {
    id: '894tuq4ut84ut8v4t8wun89g',
    parentId: "8xf0y6ziyjabvozdd253nd",
    timestamp: 1468166872634,
    body: 'Hi there! I am a COMMENT.',
    author: 'thingtwo',
    voteScore: 6,
    deleted: false,
    parentDeleted: false
  },
  "8tu4bsun805n8un48ve89": {
    id: '8tu4bsun805n8un48ve89',
    parentId: "8xf0y6ziyjabvozdd253nd",
    timestamp: 1469479767190,
    body: 'Comments. Are. Cool.',
    author: 'thingone',
    voteScore: -5,
    deleted: false,
    parentDeleted: false
  }
}

而我的API端点描述如下:

GET /comments/:id
      USAGE:
        Get the details for a single comment

EDIT 4 输出的屏幕截图。

【问题讨论】:

  • 你的组件连接到 redux 存储了吗?
  • @TimH 是的,我做到了。我使用了这行代码export default connect(mapStateToProps, { fetchPost, deletePost, editPost, fetchComments })(PostDetail);
  • 好的,这条线应该没问题。您能否检查一下您的 mapStateToProps 是否正常工作?也许发布一些console.logs
  • @TimH 我尝试在我的渲染方法中获取状态,如下所示:console.log(createStoreWithMiddleware.getState()); 它显示了 cmets 在 cmets 状态下的显示。我在上面添加了一个屏幕截图。你能有一个看?
  • 我猜这很可能是因为初始状态 cmets 在 redux 存储中为 null 并且直到 cmets 可从 FETCH_COMMENTS 操作中获得

标签: javascript reactjs redux


【解决方案1】:

您需要检查一些事项

首先:下面的reducer是一个注释reducer,state.comments没有定义,所以...state.comments会失败。所以你需要像state = {comments: {}}一样更新initialState

import { FETCH_COMMENTS } from '../actions/comment_action';

export default function(state = {comments: {}}, action) {
    switch (action.type) {
      case FETCH_COMMENTS:
          return {comments: {...state.comments, ...action.payload.data}};

      default:
        return state;
    }
}

第二:mapStateToProps function mapStateToProps({ posts, comments }, ownProps) { 中的帖子和组件是reducers,因此posts[ownProps.match.params.id]comments[ownProps.match.params.id] 不是你想要的,但是

function mapStateToProps({ posts, comments }, ownProps) {
    return {
      post: Object.values(posts.posts).find(post => post.id ===ownProps.match.params.id),
      comment: Object.values(comments.comments).find(comment => comment.id ===ownProps.match.params.id};
}

第三:既然 cmets 是使用 fetchComments 操作更新的,你应该在组件中使用它之前检查评论,比如

if(this.props.comment) {
    //do what you want with comment here
}

或者如果你在 JSX 中使用它,像这样使用它

{this.props.comment ? <div>{this.props.comment}</div>: null}

【讨论】:

  • 如果我按照您提到的那样更改 mapStateToProps,我的评论状态出现错误。我收到如下错误:TypeError: Cannot read property '8xf0y6ziyjabvozdd253nd' of undefined。我在服务器文件的编辑中添加了上面的默认评论对象。 '8xf0y6ziyjabvozdd253nd' 是该评论所属的帖子的 ID。请您看一下。也许我在从帖子中正确获取评论时犯了一些错误。
  • 你是不是也把postReducer的初始状态改成了state = {posts: {}}
  • 对不起,我忘了早点做出改变。但是现在,即使在添加 state = {posts: {}} 并像这样更改我的 mapStateToProps 之后:`function mapStateToProps({ posts, cmets }, ownProps) { return {帖子:posts.posts[ownProps.match.params.id],评论:cmets.cmets[ownProps.match.params.id]}; }' ,它在渲染方法的条件下没有返回 true。但是我可以在我的 redux devtools 中看到评论。我已经粘贴了上面的截图。
  • 我的情况也是这样的:{ (this.props.comment) ? &lt;div&gt; COMMENTS AVAILABLE &lt;/div&gt; : &lt;div&gt; NOT AVAILABLE &lt;/div&gt; }
  • 你在 mapStateToProps 函数中得到ownProps.match.params.id。如我所见,您键入 cmets 不是 ownProps.match.params.id ,而是它似乎是一个对象数组
【解决方案2】:

由于您在 mapStateToProps 中使用了“评论”。

您可以使用 {this.props.comment} 而不是 {this.props.cmets} 访问它

如果这有帮助,请告诉我。

【讨论】:

    【解决方案3】:

    你必须从 react-redux 导入 connect 方法,然后使用 mapStateToProps 到 connect 方法,比如:

          import { connect } from 'react-redux';
          class ComponentName extends Component {
          }
          function mapStateToProps({ posts, comments }, ownProps) {
            return {
                post: posts[ownProps.match.params.id],
                comment: comments[ownProps.match.params.id]};
          }  
          export default connect(mapStateToProps)(ComponentName);
    

    【讨论】:

    • 我已经按照上面的步骤做了,还是不行。
    • 您在尝试使用 this.props.cmets 吗?检查变量名。您可以通过 this.props.comment 访问它。
    猜你喜欢
    • 2017-12-26
    • 2020-10-26
    • 2021-05-04
    • 2020-07-15
    • 1970-01-01
    • 2020-10-15
    • 2019-02-27
    • 1970-01-01
    • 2016-01-02
    相关资源
    最近更新 更多