양식 작성(2): 자체 호스팅 상태

18336 단어 formreact
HTML에서 <input> , <textarea><select> 와 같은 양식 요소는 일반적으로 자체 상태를 유지하고 사용자 입력에 따라 업데이트합니다.

우리는 이 기능을 이용할 수 있습니다. 그러나 먼저 제어되는 구성 요소에 대해 이야기하십시오.

제어되는 구성 요소




function FreeInput({ defaultValue }: { defaultValue: string }) {
  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value);
  };
  return <input type="text" onChange={handleChange} defaultValue={defaultValue} />;


값이 자체 호스팅되기 때문에 <input>e.target.value에서 onChange의 값에 항상 액세스할 수 있습니다.

FreeInput는 소품defaultValue만 노출하여 초기 값을 받습니다.

그러나 이 자체 호스팅 값을 속성으로 input.value에 전송하여 React 상태와 결합하는 경향이 있습니다.

function ControlledInput({ defaultValue }: { defaultValue: string }) {
  const [value, setValue] = useState(defaultValue);
  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value);
    setValue(e.target.value);
  };
  return <input type="text" value={value} onChange={handleChange} />;
}


대부분의 상황에서 value의 상태는 부모 구성 요소에서 소품으로 전송됩니다.

function FormAsController() {
  const [value1, setValue1] = useState("1");
  const [value2, setValue2] = useState("2");
  const [value3, setValue3] = useState("3");
  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    console.log("Let's Submit: ", [value1, value2, value3]);
  };
  return (
    <form onSubmit={handleSubmit}>
      <InputControlledByParent value={value1} onChange={setValue1} />
      <InputControlledByParent value={value2} onChange={setValue2} />
      <InputControlledByParent value={value3} onChange={setValue3} />
      <button type="submit">Submit</button>
    </form>
  );
}

function InputControlledByParent({ value, onChange }: { value: string; onChange: (value: string) => void }) {
  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value);
    onChange(e.target.value);
  };
  return <input type="text" value={value} onChange={handleChange} />;
}

ControlledInputInputControlledByParent 모두 자체 호스팅 값이 React 상태에 의해 제어되기 때문에 제어 구성 요소라고 합니다.

이것은 "Single Source of Truth"원칙을 준수하기 위한 것입니다React Docs .

잠재적인 문제



구성 요소value의 상태InputControlledByParent를 구성 요소FormAsController에 넣으면 다시 렌더링 문제가 발생할 수 있습니다.
InputControlledByParent가 값을 업데이트하면 모든 FormAsController를 포함하여 전체 InputControlledByParent가 다시 렌더링됩니다.

아, 그건 좀 역겹군요. 특히 영향을 받아서는 안 되는 다른 구성 요소가 있습니다.

확실히 우리는 각각 InputControlledByParentReact.useMemo 로 감쌀 수 있지만 오늘은 그렇지 않습니다. 저는 React.useRef 를 선호합니다.

더 나은 방법



우리가 자체 호스팅 기능을 사용할 것이라는 것을 아직도 기억하십니까? 여기 있습니다.
React.useRef 를 사용하면 각각의 Input는 자신의 값을 호스팅하고 업데이트할 때만 최신 값을 Form로 보낼 수 있습니다.

function DemocraticForm() {
  const refValueList = useRef(["", "", ""]);
  const updateValueList = (index: number, value: string) => {
    refValueList.current[index] = value;
  };
  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    console.log("Let's Submit: ", refValueList.current);
  };
  return (
    <form onSubmit={handleSubmit}>
      <SelfHostedInput defaultValue={"0"} onChange={(v) => updateValueList(0, v)} />
      <SelfHostedInput defaultValue={"1"} onChange={(v) => updateValueList(1, v)} />
      <SelfHostedInput defaultValue={"2"} onChange={(v) => updateValueList(2, v)} />
      <button type="submit">Submit</button>
    </form>
  );
}

function SelfHostedInput({ defaultValue, onChange }: { defaultValue: string; onChange: (value: string) => void }) {
  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value);
    onChange(e.target.value);
  };
  return <input type="text" defaultValue={defaultValue} onChange={handleChange} />;
}


이제 SelfHostedInput는 진정한 자체 호스팅이며 업데이트로 인해 Form가 다시 렌더링되지 않습니다.

This way only works in the situation where the Form's UI is NOT dependent on any input value.



다음 부분에서는 각 입력에 대해 유용한 유효성 검사기를 사용자 지정하는 방법에 대해 이야기하겠습니다.

좋은 웹페이지 즐겨찾기