【问题标题】:Redux issue with erroractions may not have an undefined "type" property错误操作的 Redux 问题可能没有未定义的“类型”属性
【发布时间】:2021-12-23 07:51:47
【问题描述】:

我是第一次在 API 中使用带有异步调用的 redux。我正面临这个错误的问题“动作可能没有未定义的“类型”属性。”

如果有人熟悉 redux,请检查此代码。我还更正了下面的文件名。

我的代码如下:

actionTypes.js

export const SET_LOGIN_STATE = "SET_LOGIN_STATE"

actions.js

import * as t from '../constants/actionTypes';

const setloginState = (logindata) => {

    return {
        type: t.SET_LOGIN_STATE,
        payload: logindata,
    }

}

reducer.js

import * as t from '../constants/actionTypes';


const initialState = {
    isLoggedIn: false,
    userId: '',
    token: '',
    refreshToken: '',
    expiresOn: '',
    data: '',
  };

  
export const loginReducer = (state = initialState, action) => {
  switch (action.type) {
    case t.SET_LOGIN_STATE:
      return {
        ...state,
        ...action.payload, // this is what we expect to get back from API call and login page input
        isLoggedIn: true, // we set this as true on login
      };
    default:
      return state;
  }
};

store.js

    import thunkMiddleware from 'redux-thunk';
    import { createStore, combineReducers, applyMiddleware } from 'redux';
    //import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly'; // this is for debugging with React-Native-Debugger, you may leave it out
    import { loginReducer } from '../reducers/reducer';

const rootReducer = combineReducers({
  loginReducer: loginReducer,
});

export const store = createStore(
  rootReducer,
  applyMiddleware(thunkMiddleware)
);

UI - app.js

    import logo from './logo.svg';
    import './App.css';
    import axios from 'axios';
    import {useForm} from 'react-hook-form';
    import {useDispatch} from 'react-redux';
    import {login} from './actions/actions';
    
    function App() {
      const { register, formState: { errors }, handleSubmit } = useForm();
    
      const _doLogin =  async data => {
          
    
            // axios post
            return (dispatch) => { 
            axios.post('/invoice/webapps/api/login', data, {
                headers: {
                   Accept: 'application/json',
                  'Content-Type': 'application/json'
                }})
              .then(function (response) {
                var responsedata=JSON.parse(JSON.stringify(response));
                if(responsedata.data.login_status === "Done"){
    
            console.log("correct");
                  //  localStorage.setItem("authtoken", responsedata.data.api_token);
                  //dispatch(setLoginState('correct'));
                
                }
                else{ /// invalid login
    
            console.log("correct");
                
                }
              })
              .catch(function (error) {
                //Swal.fire("Error", error, "warning");
                console.log(error);
              });
    
        }
    
    }
    
    
      return (
        <div className="App">
          <div>Login 
          <form className="form" onSubmit={handleSubmit(useDispatch(_doLogin))}>
            Enter your username : <input className="form-control h-auto form-control-solid py-4 px-8" type="text" 
                                        placeholder="Email"  autoComplete="off" {...register("email", {
                                            required: true, 
                                            pattern: {
                                               value: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
                                               message: 'Please enter a valid email',
                                           }, })}/>
            Enter your password :   <input className="form-control h-auto form-control-solid py-4 px-8" type="password"
                                         placeholder="Password" autoComplete="off" 
                                         {...register("password", {
                                             required: true, 
                                             })} />
            <input type="submit" value="Login"/>
            </form>
          </div>
        </div>
      );
    }
    
    export default App;

【问题讨论】:

  • 您的文件名看起来很可疑。包含实际类型SET_LOGIN_STATE 的文件的名称是什么?您在其上方有名称 Actiontype.js,但似乎您正在从 ../constants/actionTypes 导入类型
  • 再次检查。这是错别字。我更正了文件名。

标签: reactjs redux react-redux redux-thunk


【解决方案1】:

我认为这不是 useDispatch 的使用方式。在组件的主体上,您需要像这样调用它:

const dispatch = useDispatch();

然后在你的_doLogin中使用它

绑定你的 submitHandler 应该像这样:onSubmit={handleSubmit(_doLogin)}

完整的代码是:

import logo from './logo.svg';
import './App.css';
import axios from 'axios';
import {useForm} from 'react-hook-form';
import {useDispatch} from 'react-redux';
import {setLoginState} from './actions/actions';
    
function App() {
  const { register, formState: { errors }, handleSubmit } = useForm();
  const dispatch = useDispatch();
    
  const _doLogin =  async data => {
    //axios post
    return axios.post('/invoice/webapps/api/login', data, {
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      }}).then(function (response) {
        var responsedata=JSON.parse(JSON.stringify(response));
        if(responsedata.data.login_status === "Done"){
         console.log("correct");
         //localStorage.setItem("authtoken", responsedata.data.api_token);
         dispatch(setLoginState('correct'));
       } else {
        // invalid login
       }
      }).catch(function (error) {
                //Swal.fire("Error", error, "warning");
                console.log(error);
     });    
    }
    
    
      return (
        <div className="App">
          <div>Login 
          <form className="form" onSubmit={handleSubmit(_doLogin)}>
            Enter your username : <input className="form-control h-auto form-control-solid py-4 px-8" type="text" 
                                        placeholder="Email"  autoComplete="off" {...register("email", {
                                            required: true, 
                                            pattern: {
                                               value: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
                                               message: 'Please enter a valid email',
                                           }, })}/>
            Enter your password :   <input className="form-control h-auto form-control-solid py-4 px-8" type="password"
                                         placeholder="Password" autoComplete="off" 
                                         {...register("password", {
                                             required: true, 
                                             })} />
            <input type="submit" value="Login"/>
            </form>
          </div>
        </div>
      );
    }
    
    export default App;

编辑 1

确保您从 actions.js 导出您的操作并正确设置它的名称LoginState

【讨论】:

  • 我认为调度应该是一个 axios 块。但我会检查并在这里告诉你。
  • 同样的错误“错误:动作可能没有未定义的“类型”属性。您可能拼错了动作类型字符串常量。”
  • 您是否尝试将所有出现的t.SET_LOGIN_STATE 替换为字符串'SET_LOGIN_STATE'?如果这解决了您的问题,那么您有一些拼写错误的导入。我没有您的完整目录结构来验证您​​的导入。
  • 这里提一下我的目录结构 1 actions/actions.js 2. constants/actionTypes.js 3. reducers/reducer.js 4. store/store.js 外层是app.js, index .js 代码与上面提到的相同。如果您可以使用您的登录 api。
  • @wontone_boys 检查我的编辑,您似乎拼错了 setLoginState,据我所知,您也没有导出它。
猜你喜欢
  • 1970-01-01
  • 2019-05-09
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
相关资源
最近更新 更多