【问题标题】:React getting Invalid state while using async action creator with redux-thunk使用带有 redux-thunk 的异步操作创建器时反应获取无效状态
【发布时间】:2020-03-22 09:08:07
【问题描述】:

在我的应用程序组件中,我有包含用户 ID 的帖子列表,我想根据该用户 ID 显示用户名和详细信息,这是我的应用程序组件的 jsx:

应用组件 JSX:

render() {
    const posts = [...someListOfPosts];
    return posts.map((post) => {
        return (
            <div className="item" key={post.id}>
                <div className="content">
                    <User userId={post.userId} />
                </div>
            </div>
        );
    });
}

用户组件

import React from 'react';
import { connect } from 'react-redux';
import { fetchUser } from '../actions';

class UserHeader extends React.Component {

    componentDidMount() {
        this.props.fetchUser(this.props.userId); // getting correct userId
    }

    render() {
        const { user } = this.props;
        // Not displaying correct user i.e. showing the last resolved user for each post
        return (
            <div>
                {user && <div className="header">{user.name}</div>}
            </div>
        );
    }
}

const mapStateToProps = (state, props) => {
    return {
        user: state.user
    };
}

export default connect(mapStateToProps, { fetchUser })(UserHeader);

我正在为 userId 获得正确的道具,但对于每个帖子,它都会显示来自 api 的最后一个已解决的用户。它应该是每个帖子的相关用户。

Reducer 和 Action Creator

// action

export const fetchUser = (id) => {
    return async (dispatch) => {
        const response = await axios.get(`https://jsonplaceholder.typicode.com/users/${id}`);
        dispatch({
            type: 'FETCH_USER',
            payload: (response.status === 200 && response.data) ? response.data : null; // it returns single user not array of user
        });
    }
}

// reducer

export default (state = null, action) => {
    switch (action.type) {
        case 'FETCH_USER':
            return action.payload; // i know it can be fixed by defaulting state to empty array and returning like so [...state, action.payload] but why should i return complete state why not just a single user object here?
        default:
            return state;
    }
}

fetchUser 操作创建者返回用户的单个有效负载而不是数组,那么为什么需要返回像 [...state, action.payload] 这样的状态,为什么不能通过仅返回 action.payload 来完成呢?我已经通过仅返回action.payload 进行了尝试,但在我的用户组件中,它每次都显示来自 api 的最后一个解析的用户。我对此感到困惑。

【问题讨论】:

  • 您将初始状态默认为 null - 默认为空数组
  • 我需要明白为什么我需要从reducer返回一个数组?为什么不能通过从 api 返回的单个对象来完成?
  • 您需要保持返回值一致且可预测。如果您随机返回一个对象而不是一个数组,那么您将在某处使用array.pop() 或其他东西并得到一个错误并想知道发生了什么
  • 我明白了您将初始状态默认为空数组的观点,但问题是 fetchUser 操作创建者返回用户的单个有效负载而不是数组,那么为什么需要返回像 [...state, action.payload]; 这样的状态@为什么不能只返回action.payload 来完成吗?我已经通过仅返回action.payload 进行了尝试,但在我的用户组件中,它每次都显示来自 api 的最后一个解析的用户。我对此感到困惑。
  • “为什么我需要返回完整的数组”,因为您正在这样做 - state.user.find(user =&gt; user.id === props.userId) 用于数组

标签: reactjs redux react-redux redux-thunk


【解决方案1】:

您正在使用 mapStateToProps 订阅商店,当商店发生变化时,它会重新呈现。当您尝试通过用户组件中的道具进行渲染时,应用程序会保留用户的最后一个值并重新渲染所有旧的用户组件。如果您想忽略 props 更新,则将结果设置为组件本地。

你可以试试这个:

import React from 'react';
import { connect } from 'react-redux';
import { fetchUser } from '../actions';

class UserHeader extends React.Component {
constructor(props){
super(props);
this.state={
userDetails:{}
}
}

    componentDidMount() {
fetch(https://jsonplaceholder.typicode.com/users/${this.props.userId})
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            userDetails: result.data
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          this.setState({
            isLoaded: false
          });
        }
      )

    }

    render() {
        return (
            <div>
                {this.state.userDetails && <div className="header">{this.state.userDetails.name}</div>}
            </div>
        );
    }
}

const mapStateToProps = (state, props) => {
    return {

    };
}

export default connect(mapStateToProps, { fetchUser })(UserHeader);

【讨论】:

    猜你喜欢
    • 2020-07-18
    • 2018-01-31
    • 1970-01-01
    • 2017-10-23
    • 2016-09-19
    • 2017-03-03
    • 2021-01-22
    • 2016-09-22
    • 2020-10-28
    相关资源
    最近更新 更多