Я получаю сообщение об ошибке: действия должны быть простыми объектами. Используйте пользовательское промежуточное программное обеспечение для действий asyn c. После интенсивных поисков так и не удалось решить эту проблему. Я пытаюсь получить свой токен из локального хранилища. Токен есть, но он не может работать
Так что мой код выглядит так:
Мое приложение. js
import React, { useEffect } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './redux/store';
import MainLayout from '../src/components/layout/MainLayout/MainLayout';
import Landing from '../src/components/views/Landing/Landing';
import Login from '../src/components/features/Login/Login';
import Register from '../src/components/features/Register/RegisterContainer';
import Alerts from '../src/components/common/Alerts/AlertsContainer';
import { setAuthToken } from './utils/utils';
import { loadUser } from './redux/AuthReducer';
const App = () => {
useEffect(() => {
setAuthToken(localStorage.token);
store.dispatch(loadUser());
}, []);
return (
<Provider store={store}>
<div>
<BrowserRouter>
<MainLayout>
<Route exact path='/' component={Landing} />
<section className='container'>
<Alerts />
<Switch>
<Route exact path='/register' component={Register} />
<Route exact path='/login' component={Login} />
</Switch>
</section>
</MainLayout>
</BrowserRouter>
</div>
</Provider>
);
};
export default App;
Мой магазин. js и это сводит меня с ума, так как большинство решений, которые я нашел, связано с тем, что я не использую Thunk
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
// import { composeWithDevTools } from 'redu-devtools-extension';
import thunk from 'redux-thunk';
import alerts from './AlertReducer';
import auth from './AuthReducer';
// initial state
const initialState = {};
// define reducers
const reducers = {
auth: auth,
alerts: alerts,
};
// add blank reducers for initial state properties without reducers
Object.keys(initialState).forEach((item) => {
if (typeof reducers[item] == 'undefined') {
reducers[item] = (statePart = null) => statePart;
}
});
// combine reducers
const combinedReducers = combineReducers(reducers);
//create store
const store = createStore(
combinedReducers,
initialState,
compose(
applyMiddleware(thunk),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
Финлай, мой редуктор
import axios from 'axios';
import { setAlert } from './AlertReducer';
import { setAuthToken } from '../utils/utils';
/* action name creator */
const reducerName = 'auth';
const createActionName = (name) => `app/${reducerName}/${name}`;
/* action types */
export const REGISTER_SUCCESS = createActionName('REGISTER_SUCCESS');
export const REGISTER_FAIL = createActionName('REGISTER_FAIL');
export const USER_LOADED = createActionName('USER_LOADED');
export const AUTH_ERROR = createActionName('AUTH_ERROR');
/* action creators */
export const registerSuccesAction = (payload) => ({
payload,
type: REGISTER_SUCCESS,
});
export const registerFailAction = (payload) => ({
payload,
type: REGISTER_FAIL,
});
export const userLoadSuccess = (payload) => ({
payload,
type: USER_LOADED,
});
export const userAuthError = (payload) => ({
payload,
type: AUTH_ERROR,
});
/* actions THUNK */
//load user
export const loadUser = () => {
return async (dispatch) => {
if (localStorage.token) {
dispatch(setAuthToken(localStorage.token));
}
try {
const res = await axios.get('/api/auth');
dispatch(userLoadSuccess(res.data));
} catch (err) {
dispatch(userAuthError({ name: 'AUTH_ERROR' }));
}
};
};
//post user
export const registerUser = ({ name, email, password }) => {
return async (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({ name, email, password });
try {
const res = await axios.post(
'/api/users',
//http://localhost:8000/api/users
body,
config
);
dispatch(registerSuccesAction(res.data));
} catch (err) {
const errors = err.response.data.errors;
// console.log(err.response.request._response);
if (errors) {
errors.forEach((error) => dispatch(setAlert(error.msg, 'danger')));
}
dispatch(registerFailAction({ name: 'REGISTER_FAIL' }));
}
};
};
/* initial state */
const initialState = {
//store toke in localstorage
token: localStorage.getItem('token'),
isAuthenticated: null,
loading: true,
user: null,
};
/* reducer */
export default function reducer(state = initialState, action) {
switch (action.type) {
// register
case REGISTER_SUCCESS:
localStorage.setItem('token', action.payload.token);
return {
...state,
...action.payload,
isAuthenticated: true,
loading: false,
};
case REGISTER_FAIL:
case AUTH_ERROR:
localStorage.removeItem('token');
return {
...state,
token: null,
isAuthenticated: null,
loading: false,
};
//user loading
case USER_LOADED:
return {
...state,
isAuthenticated: true,
loading: false,
user: action.payload,
};
default:
return state;
}
}
Я использую Thunk, но все еще могу Получите это работает. Большинство решений, которые я нашел, касаются того, что люди не используют "()" в useEffect.
Спасибо за помощь
Еще одна вещь, которую я пытался сделать в компоненте класса, но это не приближало меня к решению этого
// редактировать это setAuthToken
import axios from 'axios';
// set global default header for token stored in localstorage
export const setAuthToken = (token) => {
if (token) {
axios.defaults.headers.common['x-auth-token'] = token;
} else {
delete axios.defaults.headers.common['x-auth-token'];
}
};