首页 > 解决方案 > 错误:操作必须是普通对象。使用自定义中间件进行异步操作 Redux

问题描述

我收到错误:操作必须是普通对象。使用自定义中间件进行异步操作。经过激烈的搜索仍然无法解决这个问题。我正在尝试从本地存储中获取我的令牌。令牌在那里但无法正常工作

所以我的代码如下所示:

我的 App.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;

我的 store.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;

一个finlay我的减速机

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 ut 仍然无法正常工作。此外,我发现的大多数解决方案都是关于人们在 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'];
  }
};

标签: javascriptreactjsreduxreact-redux

解决方案


推荐阅读