问题描述
编辑: 我已经稍微调整了我的代码,现在我很确定无论进来什么,我的减速器在“动作”处都返回未定义的。所以我认为这是问题所在,或者是组合减速器。此外,我还返回了固定变量,但我仍然未定义
我没有看到错误隐藏在哪里,但我怀疑是我的减速器太慢了。
我的目标是什么,我的目标是从一个 api 中获取所有成员。 为此,我使用了 combinereducer 和 thunk。
另外我使用了await函数,请求被正确地发出和接收。不幸的是,结果出现得太晚了,并且不再被 react 考虑,这让我感到疑惑。所以我怀疑我的减速器可能设置错误。
这是我的代码:
// file: myAPP/src/index.js
import React,{ Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore,applyMiddleware} from 'redux';
import thunkMiddleWare from "redux-thunk";
import './style/index.css';
import App from './App';
import reducer from './reducer/index';
let store = createStore(reducer,applyMiddleware(thunkMiddleWare));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,document.getElementById('root')
);
这是我处理请求的操作 (myAPP/src/action/action.js):
import axios from 'axios';
export const getMemberList = () => {
return function(dispatch){
axios.get("http://192.168.178.58")
.then(result =>{
dispatch({type: "memberList",payload:result.data})
})
}
}
处理存储结果的我的减速器 (myApp/src/reducer/member.js) + 我的组合减速器:
let initialState = [];
const member = (state = initialState,action) => {
if (action?.type === "memberList") {
console.log("member.js: ",action.payload);
return action.payload
} else {
return state
}
}
export default member;
----- NEW FILE -----
import { combineReducers } from 'redux';
import reducer from './reducer';
import members from './member';
let reduce = combineReducers({
memberList: members,members: reducer
});
export default reduce;
至少是我的应用程序发生错误的地方 (myApp/src/app.js):
import React from 'react';
import {connect} from 'react-redux';
import './style/App.css';
import Member from './Member';
import { getMemberList } from './action/action';
class App extends React.Component {
constructor(props){
super(props);
this.state = {
data : []
}
this.props.getMemberList();
}
render() {
console.log(this.props) //<--- *3
return (
<div className="App">
{
this.state.data?.length >= 2 ?(
console.log(this.props.membersList) //<---- *4
) : null
}
</div>
);
}
}
let mapStatetoProps = function(state){
return ({
membersList: state
})
}
let mapdispatchToProps = {
getMemberList : getMemberList
}
let AppContainer = connect(mapStatetoProps,mapdispatchToProps)(App)
export default AppContainer;
1-3 的所有标记都是空的。
但是如果我去'myApp/src/action/action.js'。 我看到它是成功的。但正如我开头所说,我认为保存是错误的。
无论如何它没有被渲染,也没有显示......所以结果看到*4没有显示。
有什么想法吗?
解决方法
我相信问题就在这里 - 您必须记住 this.props
直到下一次渲染才会更新,因此当您在那里执行 this.setState
时,它总是将其设置为您调用 getMemberList
之前的值:
await this.props.getMemberList();
this.setState({
data: this.props.membersList || [] //<---- this will still be empty,this.props
// hasn't updated yet.
});
console.log("data: ",this.props.membersList); //<---- *2
并且您的日志顺序不正确,因为 this.getTheMemberList();
没有等待(并且不能,因为它在构造函数中)。
真的,你得到了
async getTheMemberList(){
await this.props.getMemberList();
this.setState({
data: this.props.membersList || [] //<---- *2
});
console.log("data: ",this.props.membersList); //<---- *3
}
render() {
console.log(this.props) //<--- *1
最好的解决方案 (IMO) 是不使用 setState
- 直接使用道具:
class App extends React.Component {
constructor(props){
super(props);
this.props.getMemberList();
}
render() {
return (
<div className="App">
{
this.props.membersList && this.props.membersList.length >= 2 ? (
console.log(this.props.membersList)
) : null
}
</div>
);
}
}
let mapStateToProps = function(state){
return ({
membersList: state
})
}
let mapDispatchToProps = {
getMemberList : getMemberList
}
let AppContainer = connect(mapStateToProps,mapDispatchToProps)(App)
export default AppContainer;
所以对我来说有几个问题:
- 调用api
- 以及 App.js 中状态的恢复 一些文件丢失 --> import Member from './Member',members: reducer 所以我会在这里关注 membersList
我也冒昧地重构你的代码,以便解释更容易理解
对于 redux 3 文件:actions.js、reducerMember.js、store.js
//actions.js
import axios from "axios";
const loadMemberList = () => {
return {
type: "loadMemberList",};
};
const loadMemberListSucess = (items) => {
return {
type: "loadMemberListSucess",items,};
};
const loadMemberListError = (error) => {
return {
type: "loadMemberListError",error,};
};
export const getMemberList = () => {
return async (dispatch) => {
dispatch(loadMemberList());
try {
const { data } = await axios.get("http://192.168.178.58");
dispatch(loadMemberListSucess(data));
} catch (error) {
dispatch(loadMemberListError(error.message));
}
};
};
//reducerMember.js
const initialState = {
isLoading: false,error: "",members: [],};
const reducerMember = (state = initialState,action) => {
switch (action.type) {
case "loadMemberList":
return { ...state,isLoading: true };
case "loadMemberListSucess":
return { ...state,isLoading: false,members: action.items,error: "" };
case "loadMemberListError":
return { ...state,error: action.error };
default:
return state;
}
};
export default reducerMember;
//store.js
import { createStore,combineReducers,applyMiddleware } from "redux";
import thunk from "redux-thunk";
import reducerMember from "./reducerMember.js";
const store = createStore(
combineReducers({
membersList: reducerMember,//members: reducer --> I don't know what is it the ./reducer
}),applyMiddleware(thunk)
);
export default store;
现在在你的 index.js 中
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from "./store"
import './style/index.css';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,document.getElementById('root')
);
最后是你的 App.js
import React from "react";
import { connect } from "react-redux";
// import Member from './Member' --> I don't know what is it
import { getMemberList } from "./actions";
class App extends React.Component {
componentDidMount() {
this.props.getMemberList();
}
render() {
console.log(this.props.membersList.members);
return (
<div className="App">
{this.props.membersList.members.length > 0 && (
<p>{JSON.stringify(this.props.membersList.members)}</p>
)}
</div>
);
}
}
const mapStateToProps = (state) => {
return {
membersList: state.membersList,};
};
const mapDispatchToProps = (dispatch) => ({
getMemberList: () => dispatch(getMemberList()),});
export default connect(mapStateToProps,mapDispatchToProps)(App);