【问题标题】:TypeError: Cannot destructure property 'loading' of 'state' as it is undefinedTypeError:无法解构“状态”的属性“加载”,因为它未定义
【发布时间】:2021-04-13 08:21:07
【问题描述】:

这是我在 REACTJS 中的用户注册代码,每当我点击注册按钮时,redux for request 都会工作,然后它会转到 request_fail 而不是成功。在此之后,当我看到我的 mongo 集合时,数据就被完美地存储了。我在邮递员中检查了 API,所以它工作正常,所以我尽力解决错误但没有成功。 如果有人找到解决方案,那将是一个很大的帮助

import React, { useState, useEffect } from 'react';
    import { useDispatch, useSelector } from 'react-redux';
    import {
      Container, Col, Form,
      FormGroup, Label, Input,
      Button,
    } from 'reactstrap';
    import { signupuserAction } from '../../redux/actions/users/userActions';
    const Signup = ({ history }) => {
      const [name, setName] = useState('');
      const [email, setEmail] = useState('');
      const [password, setPassword] = useState('');
      const [bio, setBio] = useState('');
      const [jobtitle, setJobtitle] = useState('');
      const [tech, setTech] = useState('');
    
      const dispatch = useDispatch();
      //getting user login from store
      const state = useSelector(state => {
        return state.userLogin;
      });
      const { loading, userInfo, error } = state
    
      //Redirecting if user is login/authenticated
      useEffect(() => {
        if (userInfo) {
          history.push('/');
        }
      }, [userInfo])
      const submitHandler = e => {
        e.preventDefault();
        //dispatching action
    
        dispatch(signupuserAction(name, email, password, bio, jobtitle, tech));
      }
      return (
        <Container className="signup">
          <h2>Sign Up</h2>
          <Form className="form" onSubmit={submitHandler}>
            <Col>
              <FormGroup>
                <Label for="name">Name*</Label>
                <Input
                  type="text"
                  name="name"
                  id="name"
                  placeholder="Enter Your Full Name"
                  onChange={e => setName(e.target.value)}
                  value={name}
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Label for="email">Email*</Label>
                <Input
                  type="email"
                  name="email"
                  id="email"
                  placeholder="myemail@email.com"
                  onChange={e => setEmail(e.target.value)}
                  value={email}
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Label for="password">Password*</Label>
                <Input
                  type="password"
                  name="password"
                  id="password"
                  placeholder="********"
                  onChange={e => setPassword(e.target.value)}
                  value={password}
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Label>Bio*</Label>
                <Input
                  type="text"
                  name="bio"
                  id="bio"
                  placeholder="Enter a breif Introduction about Yourself"
                  onChange={e => setBio(e.target.value)}
                  value={bio}
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Label>Job Title*</Label>
                <Input
                  type="text"
                  name="jobtitle"
                  id="jobtitle"
                  placeholder="Sotware Developer"
                  onChange={e => setJobtitle(e.target.value)}
                  value={jobtitle}
                />
              </FormGroup>
            </Col>
            <Col>
              <FormGroup>
                <Label>Technology*</Label>
                <Input
                  type="text"
                  name="tech"
                  id="tech"
                  placeholder="ReactJS, NodeJS, Python "
                  onChange={e => setTech(e.target.value)}
                  value={tech}
                />
              </FormGroup>
            </Col>
            <Button color="primary" className="btn-submit">Submit</Button>
          </Form>
        </Container>
      );
    }
    
    export default Signup;

【问题讨论】:

  • 你能分享一下你的userLogin reducer 函数以及你如何组合你的 reducer 来为你的 redux 提供者创建你的 store 对象吗?
  • 这里是 gihtub 存储库
  • @DrewReese 上面是链接,你能查一下吗
  • 我在您的操作代码中发现了一个可能的错误(在下面的答案中解决),但无法追踪导致state 的路径(state.userLogin@ 987654325@Signup` 组件。您确定这是您访问未定义的loading 的地方吗?

标签: reactjs react-redux


【解决方案1】:

您的userReducer 功能似乎没问题,所以我检查了signupuserAction 操作。我怀疑它在成功的 POST 请求之后 在您的异步操作中引发错误。我相信您在处理 POST 请求响应时在 Promise 链中存在逻辑错误。

Reducer/Action 问题

  1. 您尝试通过控制台记录响应 res.data。由于 console.log 是一个 VOID 返回,因此您实际上是从 Promise 链返回 undefined
  2. 您尝试从undefined 解构data,这会引发错误。
  3. 外部try/catch 捕获错误,并调度USER_REGISTER_FAIL 操作。

动作

const signupuserAction = (name, email, password, bio, jobtitle, tech) => {
  return async dispatch => {
    try {
      dispatch({
        type: USER_REGISTER_REQUEST
      });
      const config = {
        headers: {
          'Content-Type': 'application/json',
        },
      };
      
      const { 
        data // <-- (2) attempt to destructure from undefined
      } = await axios.post('http://localhost:4000/app/signup', {
        name,
        email,
        password,
        bio,
        jobtitle,
        tech
      },
        config
      ).then((res) => console.log(res.data)) // <-- (1) void return
      .catch((err) => console.log(err));
      dispatch({
        type: USER_REGISTER_SUCCESS,
        payload: data
      });
      console.log(data)
      //saving user to localstorage
      //localStorage.removeItem('userAuthData');
      localStorage.setItem('userAuthData', JSON.stringify(data));
    } catch (error) { // <-- (3) catch thrown error & failure action dispatch
      console.log(error);
      dispatch({
        type: USER_REGISTER_FAIL,
        payload: error.response && error.response.data.message,
      });
    }
  };
};

也许您打算解析 JSON,或者您想记录结果并忘记返回它。

const { data } = await axios.post('http://localhost:4000/app/signup', {
  name,
  email,
  password,
  bio,
  jobtitle,
  tech
},
  config
).then((res) => {
  console.log(res.data);
  return res.data;
})
.catch((err) => console.log(err));

关于“TypeError: Cannot destructure property 'loading' of 'state' as it is undefined”错误,我无法通过代码找到导致state 未定义的路径。我的预感是它在 some 初始渲染中,并且您的 redux 状态可能尚未实例化,但这似乎不太可能。但是,您可以在 UI 中为状态提供一个备用值,以防止出现未定义的state

const { loading, userInfo, error } = state || {};

我在上面留下了评论,以便在尝试解构 loading 时仔细检查 state 的未定义位置。

【讨论】:

  • 非常感谢先生,这意味着很多。我会做提到的改变并解决你提到的事情。
猜你喜欢
  • 2020-09-19
  • 2021-04-20
  • 2020-10-07
  • 1970-01-01
  • 2021-03-08
  • 2021-05-11
  • 2021-04-04
  • 2021-08-30
  • 1970-01-01
相关资源
最近更新 更多