1

编辑:我已经稍微调整了我的代码,现在我很确定无论发生什么,我的减速器都会在“动作”处返回未定义。所以我认为这是问题所在,或者是 combinereducer。此外,我返回了固定变量,但我仍然未定义

我没有看到错误隐藏在哪里,但我怀疑我的减速器太慢了。

我的目标是什么,我的目标是从一个 api 中获取所有成员。为此,我使用 combinereducer 和 thunk。

此外,我使用 await 功能,请求被正确发出和接收。不幸的是,结果出现得太晚了,反应不再考​​虑,这让我感到奇怪。所以我怀疑我的减速器可能设置错误。

这是我的代码:

// 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 没有显示。

任何想法?

4

2 回答 2

0

我相信问题就在这里——你必须记住,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;

于 2021-05-25T20:02:00.487 回答
0

所以对我来说有几个问题:

  • 对 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, isLoading: false, members: [], 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);
于 2021-05-25T20:04:11.870 回答