제어되지 않은 입력으로 반응 리믹스

반응 제어 입력



대부분의 React 개발자와 마찬가지로 저는 제어 입력을 사용합니다. 여기에서 값과 onChange 핸들러를 각 <input />에 제공합니다.

<input
  id='name'
  value='Zelda'
  type='text'
  onChange={({target}) => changeHandler(target.value)}
/>


대안은 제어되지 않은 입력을 사용하는 것인데, 제어된 입력이 제대로 작동하기 때문에 무시했습니다. 제어된 입력은 성능이 약간 떨어집니다(키를 누를 때마다 모든 입력이 다시 렌더링됨). 50개의 입력이 필요할 수도 있습니다!

그런 다음 Remix을 사용하기 시작했습니다 ...

리믹스



Remix embraces HTML forms.


<input /> 양식 내부의 태그에는 이벤트 핸들러나 고급 상태 관리가 필요하지 않습니다.

<form>
  <input id="name" type="text" />
  <button type="submit">
    Submit Form
  </button>
</form>


HTML 양식은 입력 값을 다시 서버에 게시합니다.

서버 포스트백, 100% 무료!



Remix은 표준 HTMLForm을 기반으로 하는 @remix-run/react 네임스페이스의 form 구성 요소를 제공하여 서버 측 기능에 자동으로 연결하는 것과 같은 추가 기능을 제공합니다.

import { Form } from "@remix-run/react";

export const action = async ({ request }) => {
  const formData = await request.formData();
  const name = formData.get("name");
  //TODO: Save to Database
}

export default function MyForm() {
  return (
    <Form method="post">
      <input id="name" type="text" />
      <button type="submit">
        Submit Form
      </button>
    </Form>
  )
}


It's not a meme, with Remix it really is that easy!



위의 input는 제어되지 않는 입력입니다.

이것은 데이터를 추가하기 위한 양식을 제공하지만 편집은 어떻습니까? 해당 입력 요소에 값을 제공하면 React는 다음과 같이 불평합니다.

Warning: A component is changing an uncontrolled input of type text to be controlled.


input에 값을 제공했지만 onChange 핸들러를 제공하지 않은 경우 이 React 오류를 본 적이 있을 것입니다!

편집도 처리할 수 있도록 입력 요소를 구성 요소로 래핑합니다.



제어된 입력의 편리함과 함께 제어되지 않은 입력의 단순성과 성능을 얻으려면 ref 를 사용할 수 있습니다.

import React, {useEffect, useRef} from 'react'

const UncontrolledInput = ({
   id,
   label,
   value = '',
   type = 'text',
   ...rest
}) => {
    const input = useRef();

    useEffect(() => {
        input.current.value = value
    }, [value])

    return (
        <p>
            <label>
                {
                    label
                }
                <input
                    ref={input}
                    id={id}
                    name={id}
                    type={type}
                    {...rest}
                />
            </label>
        </p>
    )
}

input 값은 React의 useEffectuseRef 후크로 설정됩니다. Remix는 서버 포스트백을 처리하기 위해 다음을 제공합니다Form.

<Form method="post">
  <UncontrolledInput
      id='name'
      label='Name'
      value={'Zelda'}
  />
</Form>


이제 input 요소에 값을 설정하고 이벤트 핸들러나 상태 관리 없이 서버에 다시 게시할 수 있습니다. 다음으로 서버에서 데이터를 로드하기만 하면 됩니다.

전체 서버 왕복, 100% 무료!



Remix로 그림을 완성해 봅시다.

import { Form, useLoaderData } from "@remix-run/react";

export const loader = async () => {
  //TODO: Load name from Database...
  return json({ name: 'Zelda' });
};

export const action = async ({ request }) => {
  const formData = await request.formData();
  const name = formData.get("name");
  //TODO: Save to Database
}

export default function MyForm() {
  const { name } = useLoaderData();

  return (
    <Form method="post">
      <UncontrolledInput
          id='name'
          label='Name'
          value={name}
      />
      <button type="submit">
        Submit Form
      </button>
    </Form>
  )
}


제가 본 것 중 가장 쉬운 풀스택입니다!

양식 유효성 검사는 어떻습니까?



우리는 "플랫폼을 사용"하고 있기 때문에 "이벤트 버블링"을 기억하십니까?
onChange 와 같은 DOM 이벤트는 Body 태그에 도달하거나 이벤트 핸들러가 해당 이벤트를 취소할 때까지 각 상위 노드에 도달하면서 DOM 트리를 버블링합니다.

React의 이벤트 버블링



다음은 시연할 간단한 React 구성 요소입니다. 첫 번째 버튼은 button.onClick과 form.onClick을 모두 트리거합니다. 두 번째 버튼은 자체 onClick 핸들러만 트리거합니다.

const MultiEventHandler = () => (
    <form
        onClick={() => console.log('Form click handler')}
    >
        <button
            onClick={() => console.log('Button click handler')}
        >
            Fire Both Event Handlers!
        </button>
        <button
            onClick={(e) => {
                console.log('Button click handler');

                e.stopPropagation()
            }}
        >
            Fire My Event Handler
        </button>
    </form>
)


Taken to an extreme, you could have single event handlers on the body tag, to handle all events, such as, onchange and onclick (don't try)



이 Remix 예제는 Form 태그에서 단일 onChange 핸들러를 사용하여 중첩된input 컨트롤에 대한 모든 이벤트를 처리합니다.

<Form method="post"
    onChange={(e) => {
        const {id, name, value} = e.target;

        // Perform validation here!

        e.stopPropagation()
    }}
>
    <UncontrolledInput
        id='name'
        label='Name'
        value={name}
    />
    <UncontrolledInput
        id='jobTitle'
        label='Job Title'
        value={jobTitle}
    />
    <button type="submit">
        Submit Form
    </button>
</Form>


중첩된 각 onChangeinput 이벤트가 이벤트 핸들러에 의해 "캡처"되는 Form까지 버블링됩니다. 기본적으로 이벤트 핸들러 내에서 코드를 실행한 후 이벤트는 DOM 트리를 계속 버블링하여 도중에 만나는 모든 이벤트 핸들러를 트리거하지만 이벤트가 더 이상 버블링되지 않도록 stopPropagation()를 호출합니다.

좋은 웹페이지 즐겨찾기