用户数据通过Redux React App返回未定义

时间:2018-10-03 02:18:59

标签: reactjs redux

当前,我正在尝试通过Redux通过我的react应用传递用户数据。我已经使用django后端创建了一个可以正常工作的用户API,因为我可以转到url并查看其中产生的所有json。但是,当我尝试将其传递到组件中时,却一直未定义。这是我的代码:

userActions.js:

import Axios from "axios";

    export function getUser() {
      const id = this.params.match.id
      return dispatch => {
        dispatch(fetchUserBegin());
        return Axios.get(`/api/user/${id}`)
        .then((res) => {
          this.setState({
              user: res.data,

          })
        })
      }
    }

    export const FETCH_USER_BEGIN   = 'FETCH_USER_BEGIN';
    export const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS';
    export const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE';

    export const fetchUserBegin = () => ({
      type: FETCH_USER_BEGIN
    });

    export const fetchUserSuccess = user => ({
      type: FETCH_USER_SUCCESS,
      payload: { user }
    });

    export const fetchUserFailure = error => ({
      type: FETCH_USER_FAILURE,
      payload: { error }
    });

userReducer.js

import {  FETCH_USER_BEGIN, FETCH_USER_SUCCESS, FETCH_USER_FAILURE  } from '../actions/actionTypes'


const initialState = {
    user: {},
    loading: false,
    error: null
  };

  export default function productReducer(state = initialState, action) {
    switch(action.type) {
      case FETCH_USER_BEGIN:
        // Mark the state as "loading" so we can show a spinner or something
        // Also, reset any errors. We're starting fresh.
        return {
          ...state,
          loading: true,
          error: null
        };

      case FETCH_USER_SUCCESS:
        // All done: set loading "false".
        // Also, replace the items with the ones from the server
        return {
          ...state,
          loading: false,
          user: action.user
        };

      case FETCH_USER_FAILURE:
        // The request failed, but it did stop, so set loading to "false".
        // Save the error, and we can display it somewhere
        // Since it failed, we don't have items to display anymore, so set it empty.
        // This is up to you and your app though: maybe you want to keep the items
        // around! Do whatever seems right.
        return {
          ...state,
          loading: false,
          error: action.payload.error,
          user: {}
        };

      default:
        // ALWAYS have a default case in a reducer
        return state;
    }
  }

显示组件:

UserInformation.js:

import React from "react";
import { connect } from "react-redux";
import { getUser } from "../store/actions/userActions";

class UserDetailView extends React.Component {
  componentDidMount() {
    this.props.dispatch(getUser());
  }

  render() {
    const { user } = this.props;
    console.log(user)

    return (
      <ul>
        {user.map(user =>
          <li key={user.id}>{user.username}</li>
        )}
      </ul>
    );
  }
}

const mapStateToProps = state => ({
  user: state.user,

});

export default connect(mapStateToProps)(UserDetailView);

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { createStore, compose, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';

import reducer from './store/reducers/auth';


const composeEnhances = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const store  = createStore(reducer, composeEnhances(
    applyMiddleware(thunk)
))

const app = (
    <Provider store={store}>
        <App />
    </Provider>

)

ReactDOM.render(app, document.getElementById('root'));
registerServiceWorker();

任何人都知道为什么它不起作用吗?

1 个答案:

答案 0 :(得分:1)

您不应该在该动作创建者中setState()

 this.setState({
    user: res.data,
 })

您应该发送操作代替

尝试一下:

export function getUser() {
      const id = this.params.match.id
      return dispatch => {
         dispatch(fetchUserBegin());
         return Axios.get(`/api/user/${id}`)
          .then( res => { 
            dispatch(fetchUserSuccess(res.data);
         })
       }
     }

您应将mapDispatchToProps函数作为第二个参数传递给connect()方法,如下所示:

import React from "react";
import { connect } from "react-redux";
import { getUser } from "../store/actions/userActions";

class UserDetailView extends React.Component {
  componentDidMount() {
    this.props.getUser()  //fixed
  }

  render() {
    const { user } = this.props;
    console.log(user)

    return (
      <ul>
        {user.map(user =>
          <li key={user.id}>{user.username}</li>
        )}
      </ul>
    );
  }
}

const mapStateToProps = state => ({
  user: state.user,
});
const mapDispatchToProps = dispatch => ({   //added
  getUser: dispatch(getUser())
})

export default connect(mapStateToProps,mapDispatchToProps)(UserDetailView);  //fixed

并解决此问题:

   case FETCH_USER_SUCCESS:
        // All done: set loading "false".
        // Also, replace the items with the ones from the server
        return {
          ...state,
          loading: false,
          user: action.payload.user  //fixed
        };