如何使用异步操作从reducer中恢复数据

时间:2018-04-21 05:48:31

标签: javascript reactjs react-redux

Redux新手在这里 所以我有这个代码调度异步操作,它使用promise来处理请求

所以这里是mapDispatchToProps



const mapDispatchToProps = (dispatch) => {
    return {
      fetchUserList: () => {
        console.log('---In fetchUserList---');
        dispatch({
          type: FETCH_USER_LIST,
          payload: new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest();
            console.log('xhr: ', xhr);
            xhr.open('GET', 'http://localhost:5000/data/fetch/users');

            xhr.onload = () => {
              console.log(' --- in onload function ---');
              console.log(xhr.responseText);
              resolve(JSON.parse(xhr.responseText));
            }
            xhr.onerror = () => {
              console.log(' --- in onerror function ---');
              reject(xhr.statusText);
            }
            xhr.send();
          })
        });
      }




它的作用是从服务器获取json对象数组,以获取映射到

mapStateToProps



const mapStateToProps = (state) => {

  return {
    userlist: state.list_reducer,
  };
};




现在这是我上面使用的组件:



class Profile extends Component {

  constructor(props) {
    super(props);
    this.state = {
      listRender: false
    };
  }

  render() {
    console.log('In render: ');
    console.log(this.props.userlist);
    return (
      // basic list rendering template
    );
  }
  componentDidMount() {

    this.props.fetchUserList();
    this.setState({
      listRender: true
    });
  }




现在可以从上面看到我在fetchUserList()中使用componentDidMount()从服务器获取数据并且数据会发送到reducer

以下是list_reducer.js



export default function list_reducer(state = {
  operation: '',
  userlist: []
}, action) {

  switch (action.type) {
    case "FETCH_USER_FULFILLED":
      console.log("FETCH_USER_FULFILLED");
      console.log(action.payload);
      return {
        operation: 'success',
        userlist: action.payload
      }


    case "UPDATE_USER_DETAILS_FULFILLED":
      return {
        operation: 'success',
        userlist: action.payload
      }


    case "DELETE_USER_FULFILLED":
      return {
        operation: 'success',
        userlist: action.payload
      }


    case "REGISTER_USER_FULFILLED":
      return {
        operation: 'success',
        //userlist: 
      }

    default:
      return { ...state
      }
  }

};




现在,不是接收新获取的用户列表,而是获取在this.props.userlistmapStateToProps

中传递给reducer的默认数据

所以问题是如何新获取的列表而不是默认状态数据,它被赋予 reducer 。< / p>

1 个答案:

答案 0 :(得分:2)

使用Redux进行异步调用时,我使用Thunks

  

默认情况下,Redux操作创建程序不支持异步操作   比如获取数据,所以我们在这里使用Redux Thunk。咚   允许您编写返回函数的动作创建者而不是   一种行为。内部函数可以接收存储方法调度   和getState作为参数。

因此,如果您想进行API调用,我们的操作将如下所示。

Actions.js(或等效的)

import axios from "axios";

export const receiveUserLift = json = {
  return {
    type: "RECEIVE_USERS",
    payload: json
  }
}

export function fetchUserList() {
  return dispatch => {
    return axios
      .get('http://localhost:5000/data/fetch/users')
      .then(response => {
        dispatch(receiveUserLift(response))
      })
      .catch(error => console.log("FetchUserList Axios Error", error))

  }
} 

Reducer 将包含以下内容

case "RECEIVE_USERS":
  return Object.assign({}, currentState, {
    userList: action.payload
  });

组件将包含以下内容

import { fetchUserList } from "WHERE WE DECLARED OUR ARE ACTION";

 class Example extends React.Component {
  componentDidMount() {
    // You could use it anywhere, but this is how you would call the action
    this.props.fetch()
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.users === prevState.users) return null;
    return {
      users: nextProps.users
    };
  }
}


const mapStateToProps = (state, ownProps) => {
  return {
    users: state.userList
  };
};

const mapDispatchToProps = (dispatch, ownProps) => ({
  fetch: () => dispatch(fetchUserList())
});

<强>旁注

异步接收组件中的数据要求我们使用组件生命周期方法。您会在互联网上看到很多指南,建议您使用componentWillReceiveProps来执行此操作,但在将来的React版本中将删除此内容并替换为static getDerivedStateFromProps您可以阅读更多相关信息{{1} 3}}

static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.users === prevState.users) return null;

    return {
            users: nextProps.users
    };
  }

以上代码可作为粗略指南,但这是我在处理异步API调用和使用Redux进行渲染时所遵循的一般模式