React Form에서 중재자를 사용하는 것은 어떻습니까?

12120 단어 mediatorreact

수정됨



음, 아마도 Mediator를 사용하는 것은 좋은 생각이 아닙니다 :)

이벤트(또는 이벤트 유사)를 사용하여 자식에서 부모 구성 요소로 메시지를 보낼 수 있습니다.

상태를 부모 구성 요소에 두는 것은 나쁜 생각이 아닙니다.

참조하십시오!

그리고 감사합니다, 당신은 최고입니다!!!


원본 게시물



여러분, 안녕하세요. React에서 코딩을 시도할 때 우리는 일반적으로 일부 입력 구성 요소, 일부 버튼 구성 요소 및 기타로 일부 대화 구성 요소를 작성합니다.

이러한 입력 구성 요소를 재사용하는 것은 항상 어렵습니다. 동작이 다른 구성 요소에 의존하기 때문입니다.



보시다시피, 일반적인 방식으로 입력 구성 요소는 대화 상자가 어떻게 작동하는지(대화 상자의 상태를 설정하기 위해) 알아야 합니다. 제출 버튼도 상태를 가져오고 서버에 요청을 보내는 방법을 알아야 합니다. 제출 버튼은 또한 오류 메시지를 표시하는 방법을 알아야 합니다(여기에서 버튼은 상태를 errorMsg ~ "error"로 설정해야 합니다.

함수 유형에서 소품을 전달할 수 있습니다. 이러한 구성 요소를 '콜백' 함수라고 할 수 있습니다. 예를 들어:
  • 입력 구성 요소에 함수 소품을 전달하여 이벤트를 처리합니다onChange. 이제 입력 구성 요소를 변경하면 대화 상자의 상태가 변경됩니다.
  • 제출 버튼 구성 요소에 기능 소품을 전달하여 errorMsg 를 설정합니다.

  • 이제 이러한 하위 구성 요소는 대화 상자 구성 요소에 의존하지 않습니다. 이러한 구성 요소는 이제 해당 콜백 함수에만 의존합니다. 정말 좋습니다. 그러나 더 나을 수 있습니까?
  • 대화 구성 요소에 많은 입력 구성 요소가 있는 경우 많은 상태를 유지합니다. 하위 구성 요소가 상태를 유지하도록 할 수 있습니까? 그리고 하위 구성 요소가 해당 값을 가져오는 방법을 갖도록 할 수 있습니까?
  • 일반적인 방법에서는 상위 구성 요소만 논리를 처리할 수 있습니다. 부모가 많은 사건을 처리해야 한다면 어떻게 될까요? 하위 구성 요소에 호출할 메서드가 있습니까?

  • 우리는 입력 구성 요소가 대화 상자 구성 요소에 의존하도록 하고 싶지 않습니다. 나중에 다시 사용하기를 원하기 때문입니다. 따라서 가장 좋은 방법은 하위 구성 요소가 상위 구성 요소의 인터페이스에 의존하도록 하는 것입니다. 여기에서 하위 구성 요소는 함수notify에 의존하여 상위 구성 요소를 호출합니다. 그리고 부모의 일은 하위 구성 요소를 조정하는 것입니다.

    예를 들어 이제 부모 구성 요소가 있습니다. 그것의 임무는 이메일 주소로 서버에 요청을 보내는 것입니다.

    const Dialog = () => {
      const inputRef = useRef(null);
      const submitRef = useRef(null);
    
      const notify = (eventName, data) => {
        console.log(eventName, data);
    
        if (eventName === 'submit') {
          const email = inputRef.current.getContent();
          submitRef.current.submit(email);
        } else if (eventName === 'error') {
          inputRef.current.setErrorMsg(data);
        }
      }
    
      return (
        <div className={styles.dialog}>
          <Input ref={inputRef} />
          <Submit notify={notify} ref={submitRef} />
        </div>
      )
    }
    


    보시다시피 대화 상자 구성 요소는 InputSubmit 두 구성 요소에 의존합니다. 그러나 InputSubmitDialog에 의존하지 않습니다. 메서드가 있는 인터페이스에 의존합니다notify.

    좋다. 이는 Input 또는 Submit 메서드가 있는 다른 구성 요소에서 해당 구성 요소를 사용할 수 있음을 의미합니다 notify .

    그런 다음 Input를 정의해야 합니다.

    const Input = forwardRef((_prop, ref) => {
      const [content, setContent] = useState('');
      const [errorMsg, setErrorMsg] = useState(null);
    
      useImperativeHandle(ref, () => ({
        getContent: () => {
          return content;
        },
        setErrorMsg: (newErrorMsg) => {
          setErrorMsg(newErrorMsg);
        }
      }), [content]);
    
      return (
        <>
          <input
            ref={ref}
            className={styles.input}
            onChange={(e) => setContent(e.target.value)}
          />
          { errorMsg ? <span>{errorMsg}</span> : null }
        </>
      )
    })
    

    getContentsetErrorMsg 두 가지 방법이 있습니다. 따라서 부모는 구성 요소의 content를 처리할 필요가 없습니다. errorMsg도 모릅니다. Input 구성 요소에 의해 유지됩니다.

    다음은 또 다른 구성 요소Submit입니다.

    const Submit = forwardRef(({ notify }, ref) => {
      useImperativeHandle(ref, () => ({
        submit: (email) => {
          console.log('Try to fetch email:', email);
          console.error(`Sorry it (${email}) is not the vaild email`);
          notify('error', `Sorry it (${email}) is not the vaild email`);
        }
      }));
    
      return (
        <button
          ref={ref}
          className={styles.submit}
          onClick={() => notify('submit')}
        >
          Submit
        </button>
      )
    });
    


    멋지죠? Submit 구성 요소는 Dialog에게 제출을 요청할 것입니다. 그리고 Dialog는 해당 메서드를 호출하여 서버에 제출합니다. 제출 버튼을 다른 구성 요소에 넣고 싶을 때 유용합니다.

    좋은 웹페이지 즐겨찾기