活动创建者中的getState函数调用始终返回空数组

时间:2020-08-09 13:20:15

标签: reactjs redux react-redux redux-thunk

正在从组件“ UserHeader”的多个实例中对动作创建者“ fetchUser”进行多次调用。每个呼叫都应将一个用户添加到商店。在动作创建者“ fetchUser”内部,使用console.log语句使用“ getState”功能显示已添加用户的列表。第一个呼叫将用户列表显示为空,但随后的呼叫应该有一些用户。我不知道为什么“ getState”函数总是返回一个空数组。请帮忙。该代码托管在codesandbox

动作创建者

export const fetchUser = id => async (dispatch, getState) => {
    
  console.log(getState()); // Always empty array

  const response = await jsonPlaceholder.get(`/users/${id}`); // call to external API using Axios

  dispatch({ type: 'FETCH_USER', payload: response.data });

};

减速器

export default (state = [], action) => {
  switch (action.type) {
    case 'FETCH_USER':
      return [...state, action.payload];
    default:
      return state;
  }
};

UserHeader

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); // call to action creator
  }

  render() {
    const user = this.props.users.find(user => user.id === this.props.userId);

    if (!user) {
      return null;
    }

    return <div className="header">{user.name}</div>;
  }
}

const mapStateToProps = state => {
  return { users: state.users };
};

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

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import App from './components/App';
import reducers from './reducers';

const store = createStore(reducers, applyMiddleware(thunk));

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#root')
);

Link to image that shows zero Users

1 个答案:

答案 0 :(得分:0)

您在forEach中运行并创建API请求。该迭代不会等到上一个迭代完成,这就是您的商店尚未更新的原因。 如果您要控制台:

export const fetchUser = (id) => async (dispatch, getState) => {
  console.log("before:", getState());
  const response = await jsonPlaceholder.get(`/users/${id}`);
  dispatch({ type: "FETCH_USER", payload: response.data });
  console.log("after:", getState());
};

您将看到:

before: (->users don't contain values)
before: (->users don't contain values)
...
after: (->users contain values)
after: (users contain values
..

因此,基本上,您需要在每次迭代后等待。

这是我使用this article的实现(也使用mapfilter func而不是lodash func,但这是您的决定):

async function asyncForEach(array, callback) {
  for (let index = 0; index < array.length; index++) {
    await callback(array[index], index, array);
  }
}

export const fetchPostsAndUsers = () => async (dispatch, getState) => {
  await dispatch(fetchPosts());

  const postsUsersIds = getState().posts.map((ele) => ele.userId);
  const uniqueVal = postsUsersIds.filter(
    (t, i) => postsUsersIds.indexOf(t) === i
  );

  asyncForEach(uniqueVal, async (val) => {
    await dispatch(fetchUser(val));
  });
};

现在值已在fetchUser函数内部更新,您也可以在sandbox

中查看代码