【问题标题】:How to configure mapDispatchToProps with react redux?如何使用 react redux 配置 mapDispatchToProps?
【发布时间】:2019-12-19 23:39:51
【问题描述】:

下面是我的容器代码:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchMovies } from './actions';

export class Container extends Component {
  componentDidMount() {
    this.props.fetchMovies();
  }
}

const mapStateToProps = state => {
  return {
    movies: state.movies,
  };
};

function mapDispatchToProps(dispatch) {
  return {
    fetchMovies: bindActionCreators({fetchMovies}, dispatch),
  };
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Container);

行动:

export const fetchMovies = () => dispatch => {
  console.log('fetchMovies called');
  // const movieResponse = fetchAPI(apiUrl);
  // console.log('movieResponse => ', JSON.stringify(movieResponse));
  dispatch({ type: actionTypes.FETCH_MOVIES, payload: [] });
};

商店:

import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import rootReducer from '../rootReducer';

const middlewares = [thunk];

const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(...middlewares))
);

export default store;

依赖版本:

"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-bootstrap": "^1.0.0-beta.11",
"react-dom": "^16.8.6",
"react-flexbox-grid": "^2.1.2",
"react-redux": "^7.1.0",
"react-router": "^5.0.1",
"react-router-dom": "^5.0.1",
"react-scripts": "3.0.1",
"redux": "^4.0.4",
"redux-actions": "^2.6.5",
"redux-promise-middleware": "^6.1.1",
"redux-thunk": "^2.3.0",

出现错误:

TypeError: this.props.fetchMovies is not a function

我正在使用 16.8 的最新反应版本。是这个原因吗?还是我在配置中遗漏了什么?

【问题讨论】:

  • 试试这个fetchMovies: bindActionCreators(fetchMovies, dispatch),
  • 我有相同的代码,后来更新为对象,没有运气:(
  • IIRC bindActionCreators 用调度包装了函数,所以你调度它 2 次。尝试:export const fetchMovies = () => { return { type: actionTypes.FETCH_MOVIES, payload: [] }; };
  • 第二个参数只是调度,我不认为我在操作中做错了什么
  • 请问还有其他答案吗?

标签: javascript reactjs redux react-redux redux-thunk


【解决方案1】:

? 要简单得多。

我不知道你为什么使用“thunk”,我建议改为“saga”。我不喜欢在操作中添加一些逻辑(获取)的想法,但是这里的任何方式都是您的解决方案。

容器:

import React, { Component } from "react";
import connect from "./connect";

export class MovieList extends Component {
  componentDidMount() {
    this.props.fetchMovies();
  }

  render() {
    const { isFetching, movies } = this.props;
    const toLi = (movie, key) => <li key={key}>{movie.title}</li>;

    return isFetching
      ? <span>Data is loading</span>
      : <ul>{movies.map(toLi)}</ul>
  }
}

export default connect(MovieList); // pay attention to this

将容器与 store 绑定,这样可以让你的容器更像组件:

import { connect } from "react-redux";
import { fetchMovies } from "../actions";

const props = state => ({
  movies: state.movies,
  isFetching: state.isFetching
});

const actions = {
  fetchMovies
};

export default connect(
  props,
  actions
);

动作文件:

export const FETCH_MOVIES = `MOVIE/FETCH_MOVIES`;
export const FETCHED_MOVIES = `MOVIE/FETCHED_MOVIES`;
export const FETCH_ERROR = `MOVIE/FETCH_ERROR`;

export const receivedMovies = movies => ({
  type: FETCHED_MOVIES,
  movies
});

export const onError = error => ({
  type: FETCH_ERROR,
  error
});

export const fetchMovies = () => dispatch => {
  dispatch({type: FETCH_MOVIES})

  return fetch(API_URL)
    .then(res => res.json())
    .then(data => dispatch(receivedMovies(data)))
    .catch(err => dispatch(onError(err)));
}  

? 完整的工作演示在这里:https://codesandbox.io/s/7h56r

【讨论】:

  • ,感谢您的演示。这个例子是有 Saga 还是没有? saga怎么用?
  • 我不想让任何试图回答的人失望,因此我的投票是 +1。但是在与提供的演示链接进行比较后,我的问题仍然必须弄清楚
  • 联系我(查看我的个人资料)我将尝试解释如何使用 saga。
【解决方案2】:

您使用了错误的 bindActionCreators。它接受一个对象作为第一个参数。对象的属性就是动作创建者本身。

并像 mapDispatchToProps 一样返回一个对象。

这可能有效

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchMovies }, dispatch)
}

或者你可能根本不使用 bindActionCreators

function mapDispatchToProps(dispatch) {
  fetchMovies: () => fetchMovies(dispatch)
}

【讨论】:

  • 我也试过了,还是一样的问题
  • 我已经用 mapDispatchForProps 的完整代码更新了答案
  • 很抱歉,运气不好 :(
【解决方案3】:

在使用 bindActionCreators 函数时有一点不匹配。试试这样

const matchDispatchToProps = dispatch => bindActionCreators({
    fetchMovies
}, dispatch)

【讨论】:

    【解决方案4】:

    我不使用 mapDispatchToProps,我直接使用它并且效果很好

    export default connect(
      mapStateToProps,
      { fetchMovies }
    )(Container);
    

    【讨论】:

    • 我也试过了,但仍然没有运气:(如果我使用 this.props.fetchMovies() 在组件中确实挂载了,它会抛出同样的错误。我想知道它是否是使用最新的反应版本?
    【解决方案5】:

    你需要这样称呼它:

    this.props.actions.fetchMovies()

    您可能还需要更新 mapDispatchToProps 方法。我们这样称呼我们的:

    const actions = {
     fetchMovies: fetchMoviesActionFunction, // or whatever your function is called here
    };
    
    const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(actions, dispatch) });
    

    【讨论】:

      【解决方案6】:

      你可以通过两种方式做到这一点

      const mapDispatchToProps = (dispatch) => ({
        fetchMovies: () => dispatch(fetchMovies())
      })
      

      const mapDispatchToProps = (dispatch) => ({
        fetchMovies: bindActionCreators(fetchMovies, dispatch)
      })
      

      另外,请确保您正在导入连接的Container

      import Container from './container'
      

      而不是

      import { Container } from './container'
      

      进一步查看您的代码,您的操作不是纯函数,因此会导致另一个错误。这是您的代码的快速示例fix

      【讨论】:

      • 需要工作代码,这些都试过了,可惜不行。
      • 这应该可以工作,除非你没有导入连接的Container。你能告诉我你如何使用你的Container吗?它应该是 import Container from ... 而不是 import {Container} from ...
      • 在贴出的问题里,能不能参考一下问题
      • 不,不是。我在问你如何使用你的Container。即:您的app.js 执行&lt;Container&gt;..&lt;/Container&gt;
      • 对,你没有导入连接 Container 的 redux,并且不会有来自 redux 的任何道具。检查我的更新答案
      【解决方案7】:

      我会走另一条路。自从我上次使用 thunk 已经有一段时间了,但我没有使用 mapDispatchToProps 类似的方法。看看这种方法是否对你有用

      export class Container extends Component {
        componentDidMount() {
          this.props.dispatch(fetchMovies());
        }
      }
      
      const mapStateToProps = state => {
        return {
          movies: state.movies,
        };
      };
      
      export default connect(
        mapStateToProps
      )(Container);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-27
        • 2020-10-15
        • 1970-01-01
        • 2018-06-01
        • 2019-01-27
        • 2020-06-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多