当前,我正在尝试通过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();
任何人都知道为什么它不起作用吗?
答案 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
};