如何解决我无法从减速器到组件获取数据 动作减速器组件文件 app.js 文件 api.js 文件 reducer.js 文件 index.js 文件 index.html
我正在尝试将数据从reducer传递到组件并作为道具接收。
但是数据返回了UNDEFİNED,因此我尝试在reducer和action上对数据进行控制台,但这很不错。来自API的数据没有任何问题,但始终返回未定义的组件。我的错在哪里?
动作
export default ProfileTab;
import axios from 'axios';
import { BASE,API_KEY } from '../config/env';
export const FETCHED_MOVIES = 'FETCHED_MOVIES';
export function fetchMovies() {
return (dispatch) => {
axios
.get(`${BASE}s=pokemon&apikey=${API_KEY}`)
.then((result) => result.data)
.then((data) =>
dispatch({
type: FETCHED_MOVIES,payload: data.Search,}),);
};
}
减速器
import { FETCHED_MOVIES } from '../actions/movies';
const initialState = {
fetching: false,fetched: false,movies: [],error: {},};
export default (state = initialState,action) => {
switch (action.type) {
case 'FETCHED_MOVIES':
return {
...state,movies: action.payload,};
default:
return state;
}
};
组件
import React,{ Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { fetchMovies } from '../../actions/movies';
class Case extends Component {
static propTypes = {
movies: PropTypes.object.isRequired,};
constructor(props) {
super(props);
}
componentDidMount() {
this.props.fetchMovies();
}
onChangeHandler = (e) => {
this.setState({
input: e.target.value,});
};
render() {
console.log(this.props.movies);
return (
<div>
<div className="movies-root">
<div className="movies-wrapper">
<div className="movies-container safe-area">
<h1>mert</h1>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
movies: state.movies,};
};
const mapDispatchToProps = {
fetchMovies,};
export default connect(mapStateToProps,mapDispatchToProps)(Case);
解决方法
那是因为您的mapDispatchToProps函数应该返回一个对象,并以dispatch作为参数。返回的对象中的每个字段都应包含一个调度您的操作的函数。
所以尝试这样的事情:
public function loadUsers(ObjectManager $manager)
{
foreach (self::USERS as $userData)
{
$user = new User();
$user->setFirstName($userData['first_name']);
$user->setLastName($userData['last_name']);
$user->setEmail($userData['email']);
$user->setJob($userData['job']);
$user->setPassword($this->passwordEncoder->
encodePassword($user,$userData['password']));
$user->setUsername($userData['username']);
$user->setCreatedAt(new \DateTime());
$user->setRoles($userData['roles']);
$this->addReference($userData['last_name'],$user);
$manager->persist($user);
}
$manager->flush();
}
,
在connect语句中执行以下操作:
export default connect(mapStateToProps,{fetchMovies})(Case);
然后从您的代码中删除mapDispatchToProps
函数。
将道具作为对象分发是非常不正确的。试试这个,它应该可以工作。
,尽管已经有an accepted answer,但我不确定它的正确性,因为以最新的mapDispatchToProps
(16.13.1)的方式传递react
是完全有效的和react-redux
(7.2.1)版本(我不确定较早的版本)。
现在,假设您的问题包含整个代码,那么有两个重要的遗漏:
-
创建商店:
import { createStore } from "redux"; const store = createStore(reducer);
并将其传递给
Provider
组件:<Provider store={store}>
-
如果继续执行上述操作,您会看到
this.props.fetchMovies
发出以下错误:动作必须是普通对象。使用自定义中间件执行异步操作。
要对其进行修复,请按照说明进行操作并添加一个中间件,例如
thunk
:import { createStore,applyMiddleware } from "redux"; import thunk from "redux-thunk"; const store = createStore(rootReducer,applyMiddleware(thunk));
下面是完整的代码。请注意,我将fetchMovies
“拆分”为两个函数:sync和async,用于说明两者之间的区别。我还修改了您的代码(通常更短一些),以提高答案的可读性。您也可以see a live demo here:
文件 app.js
import React,{ Component } from "react";
import { connect } from "react-redux";
import { fetchMoviesSync,fetchMoviesAsyncMock } from "./api";
class App extends Component {
componentDidMount() {
this.props.fetchMoviesSync();
this.props.fetchMoviesAsyncMock();
}
render() {
return (
<div>
<div className="movies-root">
<div className="movies-wrapper">
<div className="movies-container safe-area">
{this.props.movies.join("\n")}
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => ({ movies: state.movies });
const mapDispatchToProps = {
fetchMoviesSync,fetchMoviesAsyncMock
};
export default connect(mapStateToProps,mapDispatchToProps)(App);
文件 api.js
export const FETCHED_MOVIES = "FETCHED_MOVIES";
export const fetchMoviesSync = () => ({
type: FETCHED_MOVIES,payload: ["movie1","movie2","movie3","movie4"]
});
export const fetchMoviesAsyncMock = () => (dispatch) => {
dispatch({
type: FETCHED_MOVIES,payload: ["movie5","movie6","movie7","movie8"]
});
};
文件 reducer.js
const initialState = {
movies: [],};
export default (state = initialState,action) => {
switch (action.type) {
case "FETCHED_MOVIES":
return {
...state,movies: state.movies.concat(action.payload)
};
default:
return state;
}
};
文件 index.js
import React from "react";
import ReactDOM from "react-dom";
import Case from "./app";
import reducer from "./reducer";
import { createStore,applyMiddleware } from "redux";
import { Provider } from "react-redux";
import thunk from "redux-thunk";
let store = createStore(reducer,applyMiddleware(thunk));
ReactDOM.render(
<Provider store={store}>
<Case />
</Provider>,document.getElementById("container")
);
文件 index.html
<body>
<div id="container"></div>
</body>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。