类型错误:无法读取验证时未定义的属性“值”

时间:2021-04-12 20:07:33

标签: reactjs next.js

大家好,我在尝试验证 React/NextJS 上的输入组件时遇到此错误。

未处理的运行时错误 类型错误:无法读取未定义的属性“值”

来源:

.next\static\chunks\pages\index.js (76:33) @ SignUp

  74 | name="username"
  75 | label="Nombre completo:"
> 76 | defaultValue={error.user.value}
     |                         ^
  77 | disabled={isLoading}
  78 | ref={username}
  79 | message={error.user.msg}

这是我的输入组件:

import React, { Component } from "react";
import { IoMdCheckmark } from "react-icons/io";
import { IoCloseSharp } from "react-icons/io5";

const Input = React.forwardRef((props, ref) => {
  class Input extends Component {
    render() {
      return (
        <div className={`input ${props.variant}`}>
          <div className="label">{props.label}</div>
          {props.variant === "warning" ? (
            <div
              className={`icon ${props.variant} bg-${props.variant} text-center rounded-full text-1xl p-px mt-5 mr-3`}
            >
              <IoCloseSharp />
            </div>
          ) : null}
          {props.variant === "success" ? (
            <div
              className={`icon ${props.variant} bg-${props.variant} text-center rounded-full text-1xl p-px mt-5 mr-3`}
            >
              <IoMdCheckmark />
            </div>
          ) : null}
          <input
            type={props.type}
            id={props.id}
            defaultValue={props.defaultValue}
            name={props.name}
            placeholder={props.placeholder}
            ref={ref}
            disabled={props.disabled}
          />
          <div className="message">
            {props.message === "" || props.message === undefined ? (
              <>&nbsp;</>
            ) : (
              props.message
            )}
          </div>
        </div>
      );
    }
  }
  return <Input />;
});

export default Input;

这是我要验证的组件:

import React, { useState, createRef } from "react";
import Input from "./Input";
import { FaFacebookSquare } from "react-icons/fa";
import { FcGoogle } from "react-icons/fc";
import { BiLogInCircle } from "react-icons/bi";
import { CgSpinner } from "react-icons/cg";

export default function SignUp() {
  const [isLoading, setLoading] = useState(false);
  const [error, setError] = useState({
    user: { error: "", msg: "", value: null },
    email: { error: "", msg: "", value: null },
  });
  const username = createRef();
  const email = createRef();
  const cellphone = createRef();
  const password = createRef();

  const handleLogin = (e) => {
    e.preventDefault();
    setLoading(true);

    // Full-name validation
    if (username.current.value === "") {
      setError({
        user: {
          error: "warning",
          msg: "Ingresa tu nombre completo.",
          value: username.current.value,
        },
      });
      setLoading(false);
    } else {
      setError({
        user: {
          error: "success",
          msg: "Correcto.",
          value: username.current.value,
        },
      });
    }
    // E-mail validation

    if (email.current.value === "" || email.current.value === undefined) {
      setError({
        email: {
          error: "warning",
          msg: "Ingresa tu correo electronico.",
          value: email.current.value,
        },
      });
      setLoading(false);
    } else {
      setError({
        email: {
          error: "success",
          msg: "Correcto.",
          value: email.current.value,
        },
      });
    }

    setTimeout(() => {
      setLoading(false);
    }, 3000);
  };

  return (
    <form onSubmit={(e) => handleLogin(e)}>
      <div className="w-full text-center text-2xl mb-5">Registrate</div>
      <Input
        type="text"
        id="username"
        name="username"
        label="Nombre completo:"
        defaultValue={error.user.value}
        disabled={isLoading}
        ref={username}
        message={error.user.msg}
        variant={error.user.error}
      />
      <Input
        type="text"
        id="email"
        name="email"
        label="Correo electronico:"
        defaultValue={error.email.value}
        disabled={isLoading}
        ref={email}
        message={error.email.msg}
        variant={error.email.error}
      />
      <Input
        type="text"
        id="cellphone"
        name="cellphone"
        label="Numero de celular:"
      />
      <Input
        type="password"
        id="password"
        name="password"
        label="Contraseña:"
      />
      <button
        disabled={isLoading}
        className={`flex flex-row px-3 justify-center items-center border border-black bg-black text-white focus:outline-none w-full rounded-md py-3 text-sm ${
          isLoading && `cursor-not-allowed`
        }`}
      >
        <span className="text-xl">
          <BiLogInCircle />
        </span>
        <span className="flex-1">
          {isLoading ? (
            <CgSpinner className="animate-spin text-xl mx-auto" />
          ) : (
            <div className="text-sm">Registrarme</div>
          )}
        </span>
        <span className="">&nbsp;</span>
      </button>

      <hr className="my-5" />
      <button
        type="button"
        className="flex flex-row px-3 justify-center items-center border border-gray-500 focus:outline-none w-full rounded-md py-3 text-sm"
      >
        <span className="text-xl">
          <FcGoogle />
        </span>
        <span className="flex-1">Registrarme con Google</span>
        <span className="">&nbsp;</span>
      </button>
      <button
        type="button"
        className="flex flex-row px-3 mt-2 justify-center items-center border border-gray-500 focus:outline-none w-full rounded-md py-3 text-sm"
      >
        <span className="text-xl text-blue-400">
          <FaFacebookSquare />
        </span>
        <span className="flex-1">Registrarme con Facebook</span>
        <span className="">&nbsp;</span>
      </button>
    </form>
  );
}

当我尝试执行提交时,它向我发送了错误。 知道我做错了什么吗? 谢谢:)

1 个答案:

答案 0 :(得分:0)

@NadiaChibrikova,感谢您发现我的错误。

我改变了更新状态的方法。

错误:我正在擦除状态。

setError({user: {
          error: "warning",
          msg: "Ingresa tu nombre completo.",
          value: username.current.value,
        }); 

正确:更新 prevState。

setError((prevState) => ({
        ...prevState,
        user: {
          error: "warning",
          msg: "Ingresa tu nombre completo.",
          value: username.current.value,
        },
      }));