React with Function Component 如何解决 Uncontrolled Component 问题?

How to solve Uncontrolled Component problem in React with Function Component?

我是做Form组件的(是Function组件) 它是不受控制的组件,因为我不想在 Input 组件中进行不必要的渲染。 却有意想不到的字眼。

  1. 我尝试在 Input 组件中使用 setState() 设置值并通过值道具 onChange 获取。它不会将整个值从 Input 传递到 Form

  2. 我不想要不必要的渲染。但是,当我在电子邮件中输入值时,同时使用密码对渲染进行反应。

我该如何解决这个问题?

代码沙盒Link https://codesandbox.io/s/makewelldonecomponents-txxl0?file=/src/Input.js

或代码

(输入组件)

import React, { useEffect, useState } from "react";

const Input = ({ type, placeholder, onChange }) => {
  const [value, setValue] = useState("");

  function handleChange(e) {
    setValue(e.target.value);
    onChange(value);
  }

  return (
    <>
      {console.log("render", placeholder)}
      <input placeholder={placeholder} value={value} onChange={handleChange} />
    </>
  );
};

export default Input;

(表单组件)

import React, { useState, useEffect } from "react";
import Input from "./Input";

const Form = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [state, setState] = useState(0);

  function handleSubmit(e) {
    e.preventDefault();
    console.log(email, password);
  }

  function handleEmail(value) {
    setEmail(value);
    console.log(value);
  }

  function handlePassword(value) {
    setPassword(value);
  }

  function handleReset(e) {
    setEmail("");
    setPassword("");
    setState(state + 1);
  }

  return (
    <form onSubmit={handleSubmit}>
      <Input
        key={state + "email"}
        type="email"
        placeholder="이메일"
        onChange={handleEmail}
      />
      <Input
        key={state + "password"}
        type="password"
        placeholder="비밀번호"
        onChange={handlePassword}
      />
      <button type="submit">가입</button>
      <button type="button" onClick={handleReset}>
        초기화
      </button>
    </form>
  );
};

export default Form;
  1. Input 组件中使用 useRef 而不是 useState
import React, { useRef } from "react";

const Input = ({ type, placeholder, onChange }) => {
  const valRef = useRef("");

  function handleChange(e) {
    valRef.current = e.target.value;
    onChange(valRef.current);
  }

  return (
    <>
      {console.log("render", placeholder)}
      <input
        placeholder={placeholder}
        value={valRef.current}
        onChange={handleChange}
      />
    </>
  );
};

export default Input;

  1. 使用 useCallbackhandleEmailhandlePassword 函数

  const handleEmail = useCallback((value) => {
    setEmail(value);
    console.log(value);
  }, []);

您可以在不使用状态和多个更改处理程序的情况下在 React 中实现不受控制的表单。

这是更新后的沙盒:

Form分量:

const Form = () => {
  const email = useRef(null);
  const password = useRef(null);

  function handleSubmit(e) {
    e.preventDefault();
    console.log(email.current.value, password.current.value);
  }

  return (
    <form onSubmit={handleSubmit}>
      <Input type="email" placeholder="이메일" ref={email} />
      <Input type="password" placeholder="비밀번호" ref={password} />
      <button type="submit">가입</button>
      <button type="reset">초기화</button>
    </form>
  );
};

export default Form;

Input 分量:

import React, { forwardRef } from "react";

const Input = forwardRef((props, ref) => {
  return <input {...props} ref={ref} />;
});