错误操作的 Redux 问题可能没有未定义的“类型”属性

Posted

技术标签:

【中文标题】错误操作的 Redux 问题可能没有未定义的“类型”属性【英文标题】:Redux issue with erroractions may not have an undefined "type" property 【发布时间】: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 导入类型 再次检查。这是错别字。我更正了文件名。 【参考方案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,据我所知,您也没有导出它。

以上是关于错误操作的 Redux 问题可能没有未定义的“类型”属性的主要内容,如果未能解决你的问题,请参考以下文章

用 jest 测试 redux 异步动作创建者

未处理的拒绝:操作未定义React js和Redux

操作可能没有未定义的“类型”属性。反应?

“无法读取未定义的属性‘类型’”在 redux 存储中用于外部包中定义的操作

调度操作后 Redux 状态未更新

Redux 存储:元素类型无效:应为字符串