以下是我的容器代码:
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
我正在使用最新的React版本16.8。那是原因吗?还是我在配置中缺少什么?
答案 0 :(得分:2)
?这要简单得多。
我不知道您为什么使用“ 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
将容器与存储区绑定,这种方式将使您的容器与组件非常相似:
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
答案 1 :(得分:1)
您使用bindActionCreators错误。它以一个对象作为第一个参数。对象的属性是动作创建者本身。
并返回一个对象,就像mapDispatchToProps一样。
这可能有效
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchMovies }, dispatch)
}
或者您可能根本不使用bindActionCreators
function mapDispatchToProps(dispatch) {
fetchMovies: () => fetchMovies(dispatch)
}
答案 2 :(得分:1)
使用bindActionCreators函数时会出现轻微的不匹配。尝试这样
const matchDispatchToProps = dispatch => bindActionCreators({
fetchMovies
}, dispatch)
答案 3 :(得分:1)
我不使用mapDispatchToProps,而是直接使用它并且效果很好
export default connect(
mapStateToProps,
{ fetchMovies }
)(Container);
答案 4 :(得分:1)
您可以通过两种方式完成
const mapDispatchToProps = (dispatch) => ({
fetchMovies: () => dispatch(fetchMovies())
})
或
const mapDispatchToProps = (dispatch) => ({
fetchMovies: bindActionCreators(fetchMovies, dispatch)
})
另外,请确保您正在导入连接的Container
import Container from './container'
代替
import { Container } from './container'
通过进一步查看代码,您的操作不是纯函数,因此导致了另一个错误。这是您的代码的快速示例fix
答案 5 :(得分:1)
您需要这样称呼它:
this.props.actions.fetchMovies()
您可能还需要更新mapDispatchToProps方法。我们这样称呼我们:
const actions = {
fetchMovies: fetchMoviesActionFunction, // or whatever your function is called here
};
const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(actions, dispatch) });
答案 6 :(得分:1)
我会另辟way径。自上次我与thunk合作以来已经有一段时间了,但是我没有使用类似mapDispatchToProps
的方法。看看这种方法是否可以帮到您
export class Container extends Component {
componentDidMount() {
this.props.dispatch(fetchMovies());
}
}
const mapStateToProps = state => {
return {
movies: state.movies,
};
};
export default connect(
mapStateToProps
)(Container);