양식을 처리하기 위한 대체 지원 드릴링(역방향, 하위에서 상위로) 방식에 대응
P粉419164700
P粉419164700 2023-09-01 19:45:14
0
2
465

저는 React를 처음 접했고 실습 프로젝트를 통해 이를 배우고 있습니다. 저는 현재 양식 처리 및 유효성 검사 작업을 하고 있습니다. 저는 SPA에서 React Router의 Form 구성 요소를 사용하고 있으며 양식 내부에는 레이블 입력과 오류 메시지를 렌더링하는 FormGroup 요소가 있습니다. 또한 FormGroup 구성 요소 내에서 자체 입력 구성 요소를 사용하여 양식에 사용되는 입력의 논리와 상태 관리를 분리합니다.

그래서 샘플 로그인 페이지에 Form 구성 요소와 FormGroup 구성 요소를 다음과 같이 배치했습니다.

pages/Login.js

'react'에서 { useState } 가져오기; import { Link, Form, useNavigate, useSubmit } from 'react-router-dom'; '../comComponents/UI/FormGroup'에서 FormGroup을 가져옵니다. '../comComponents/UI/Button'에서 버튼 가져오기; '../comComponents/UI/Card'에서 카드를 가져옵니다. import './Login.scss'; 함수 로그인페이지() { const Navigate = useNavigate(); const 제출 = useSubmit(); const [isLoginValid, setIsLoginValid] = useState(false); const [isPasswordValid, setIsPasswordValid] = useState(false); var 재설정LoginInput = null; var 재설정PasswordInput = null; isFormValid = false로 둡니다. if(isLoginValid && isPasswordValid) { isFormValid = true; } 함수 formSubmitHandler(이벤트) { event.preventDefault(); if(!isFormValid) { 반품; } 재설정로그인입력(); ResetPasswordInput(); 제출(event.currentTarget); } 함수 loginValidityChangeHandler(isValid) { setIsLoginValid(isValid); } 함수 비밀번호ValidityChangeHandler(isValid) { setIsPasswordValid(isValid); } 함수 ResetLoginInputHandler(reset) { ResetLoginInput = 재설정; } 함수 재설정PasswordInputHandler(재설정) { ResetPasswordInput = 재설정; } 함수 스위치ToSignupHandler() { 탐색('/가입'); } 반품 ( 
바둑컵

바둑컵 계정에 로그인하세요

<카드 테두리>
<양식그룹 id="로그인" label="사용자 이름 또는 이메일 주소" inputProps={{ 유형: "텍스트", 이름: "로그인", 유효성: (값) => { 값 = value.trim(); if(!값) { return [false, '사용자 이름이나 이메일 주소가 필요합니다.'] } else if(값.길이 < 3 || 값.길이 > 30) { return [false, '사용자 이름 또는 이메일 주소는 최소 3자 이상 최대 30자여야 합니다.']; } 또 다른 { return [참, null]; } }, onValidityChange: loginValidityChangeHandler, onReset: 재설정LoginInputHandler }} /> <양식그룹 id="비밀번호" label="비밀번호" sideLabelElement={ <링크="/password-reset"> 비밀번호를 잊으 셨나요? } inputProps={{ 유형: "비밀번호", 이름: "비밀번호", 유효성: (값) => { 값 = value.trim(); if(!값) { return [false, '비밀번호가 필요합니다.'] } else if(값.길이 < 4 || 값.길이 > 1024) { return [false, '비밀번호는 4자 이상, 최대 1024자여야 합니다.']; } 또 다른 { return [참, null]; } }, onValidityChange: 비밀번호 유효성 변경 핸들러, onReset: 재설정PasswordInputHandler }}/>
<버튼 클래스명="w-100" type="제출"> 로그인 또는 <버튼 클래스명="w-100" onClick={switchToSignupHandler}> 가입하기
); } 기본 로그인 페이지 내보내기;

위 코드에서 볼 수 있듯이 FormGroup 구성 요소를 사용하고 onValidityChangeonReset 속성을 전달하여 isValid< /코드의 업데이트된 값> 양식 제출 등 이후 입력 내용을 재설정하는 변경 및 재설정 기능 내 사용자 정의 후크 useInput을 사용하여 입력 구성 요소에 isValidreset 값이 변경되면 isValid 값을 전달하고 FormGroup 구성 요소에 정의된 props를 사용하여 입력 구성 요소에서 재설정 함수를 전달합니다. 또한 로그인 페이지에서 isLoginValidisPasswordValid 상태를 사용하여 하위 입력에서 전달된 업데이트된 isValid 요소. 그래서 입력 컴포넌트에 상태를 정의하고 props를 사용하여 이를 부모 컴포넌트에 전달하고 그 값을 해당 부모 컴포넌트에서 생성된 다른 상태에 저장했습니다. 진행되고 있는 소품 드릴링이 조금 불편했습니다.

상태는 입력 구성 요소 내부에서 관리되며 다음과 같은 상태를 갖습니다.

  • 값: 요소의 값을 입력합니다.
  • isInputTouched: 유효성 검사 오류 메시지가 있는 경우 표시할지 여부를 결정하기 위해 사용자가 입력을 터치/초점했는지 여부를 결정합니다.

일부 기능(예: 입력 구성 요소에 전달된 유효성 검사 기능)을 이 두 상태에 결합하고 적용하여 다른 변수 값을 생성하여 입력 및 해당 값의 유효성(예: 값이 유효한지 여부)에 대한 정보를 수집합니다. (isValid ), 확인 메시지(message)가 있는지, 입력이 유효한지(isInputValid = isValid || !isInputTouched) 확인 메시지를 표시할지 결정합니다.

이러한 상태와 값은 제가 만든 사용자 정의 후크인 useInput에서 다음과 같이 관리됩니다.

hooks/use-state.js

import { useState, useCallback } from 'react'; 함수 useInput(validityFn) { const [value, setValue] = useState(''); const [isInputTouched, setIsInputTouched] = useState(false); const [isValid, 메시지] = 유효성Fn 유형 === '함수' ? 유효성Fn(값) : [true, null]; const isInputValid = isValid || const inputChangeHandler = useCallback(event => { setValue(event.target.value); if(!isInputTouched) { setIsInputTouched(true); } }, [isInputTouched]); const inputBlurHandler = useCallback(() => { setIsInputTouched(true); }, []); const 재설정 = useCallback(() => { setValue(''); setIsInputTouched(false); }, []); 반품 { 값, 유효하다, isInputValid, 메시지, 입력ChangeHandler, 입력BlurHandler, 초기화 }; } 기본 useInput 내보내기; 

저는 현재 다음과 같이 Input.js에서 이 사용자 정의 후크를 사용하고 있습니다.

comComponents/UI/Input.js

'react'에서 { useEffect }를 가져옵니다. '../../hooks/use-input'에서 useInput을 가져옵니다. import './Input.scss'; 함수 입력(소품) { const { 값, 유효하다, isInputValid, 메시지, 입력ChangeHandler, 입력BlurHandler, 초기화 } = useInput(props.validity); const { onIsInputValidOrMessageChange, 유효성 변경, 재설정 시 } = 소품; let className = '양식 제어'; if(!isInputValid) { className = `${className} 양식-제어--잘못됨`; } if(props.className) { className = `${className} ${props.className}`; } useEffect(() => { if(onIsInputValidOrMessageChange && typeof onIsInputValidOrMessageChange === '함수') { onIsInputValidOrMessageChange(isInputValid, 메시지); } }, [onIsInputValidOrMessageChange, isInputValid, 메시지]); useEffect(() => { if(onValidityChange && typeof onValidityChange === '함수') { onValidityChange(isValid); } }, [onValidityChange, isValid]); useEffect(() => { if(onReset && typeof onReset === '함수') { onReset(리셋); } }, [onReset, 재설정]); 반품 ( <입력 {...소품} 클래스이름={클래스이름} 값={값}onChange={inputChangeHandler} onBlur={inputBlurHandler} /> ); } 기본 입력 내보내기; 

입력 구성 요소에서 isInputValid 상태를 직접 사용하여 잘못된 CSS 클래스를 입력에 추가했습니다. 하지만 isInputValid, message, isValidreset 함수도 상위 구성 요소에 전달합니다. 그것에 사용합니다. 이러한 상태와 함수를 전달하기 위해 소품에 정의된 onIsInputValidOrMessageChange, onValidityChange, onReset 함수를 사용합니다. 대신에 from 자녀가 부모에게).

다음은 FormGroup 구성 요소의 정의이며 FormGroup 내부의 입력 상태를 사용하여 유효성 검사 메시지(있는 경우)를 표시하는 방법입니다.

comComponents/UI/FormGroup.js

'react'에서 { useState } 가져오기; './Input'에서 입력 가져오기; import './FormGroup.scss'; 함수 FormGroup(props) { const [message, setMessage] = useState(null); const [isInputValid, setIsInputValid] = useState(false); let className = '양식-그룹'; if(props.className) { className = `양식 그룹 ${props.className}`; } labelCmp = ( 

위 코드에서 볼 수 있듯이 업데이트된 message isInputValid code> 입력 구성 요소에서 전달된 상태입니다. 이러한 값을 유지하기 위해 입력 구성 요소에 2개의 상태를 정의했지만 업데이트되고 전달된 값을 입력 구성 요소에 저장하려면 이 구성 요소에 또 다른 2개의 상태를 정의해야 합니다. 이것은 약간 이상하고 나에게 가장 좋은 방법이 아닌 것 같습니다.

질문은: 여기서 소품 드릴링 문제를 해결하기 위해 React Context(useContext) 또는 React Redux를 사용할 수 있다고 생각합니다. 하지만 현재 상태 관리가 좋지 않고 React Context 또는 React Redux를 사용하여 개선할 수 있는지 잘 모르겠습니다. 내가 이해한 바로는 상태가 자주 변경되는 상황에서는 React Context가 끔찍할 수 있지만 Context가 애플리케이션 전체에서 사용된다면 이것이 작동합니다. 여기에서는 전체 양식을 저장하고 업데이트하는 컨텍스트를 생성하여 양식 전체를 확장할 수 있습니다. 반면에 React Redux는 사일로에 가장 적합하지 않을 수 있으며 약간 과잉일 수도 있습니다. 어떻게 생각하나요? 이 특별한 상황에 대해 더 나은 대안은 무엇입니까?

참고: 저는 React를 처음 접하기 때문에 단순한 실수부터 일반적인 실수까지 모든 코딩에 대한 여러분의 제안에 열려 있습니다. 감사해요!

P粉419164700
P粉419164700

모든 응답 (2)
P粉627136450

React의 상태 관리에는 제어된 상태와 제어되지 않은 상태라는 두 가지 주요 사고 방식이 있습니다. 제어된 양식은 반응성을 제공하기 위해 어디에서나 값에 액세스할 수 있는 React 컨텍스트를 사용하여 제어할 수 있습니다. 그러나 제어된 입력은 특히 각 입력에서 전체 양식을 업데이트할 때 성능 문제를 일으킬 수 있습니다. 통제되지 않은 형태가 등장하는 곳입니다. 이 패러다임을 사용하면 모든 상태 관리는 상태 표시를 위한 브라우저의 기본 기능을 활용해야 합니다. 이 접근 방식의 주요 문제점은 양식의 React 측면을 잃어버리고 제출 시 양식 데이터를 수동으로 수집해야 하며 이에 대한 여러 참조를 유지하는 것이 지루할 수 있다는 것입니다.

제어된 입력은 다음과 같습니다.

으아악

EDIT: @Arkellys가 지적했듯이 양식 데이터를 수집하기 위해 반드시 참조가 필요한 것은 아닙니다.다음은FormData

을 사용한 예입니다.

통제 불능:

으아악

두 가지 접근 방식 중 하나를 사용하여 다중 구성 요소 양식을 유지하는 것은 지루하다는 것이 두 예에서 명백하므로 양식 관리를 돕기 위해 라이브러리가 자주 사용됩니다. 저는 개인적으로React Hook Form을 철저한 테스트를 거쳐 잘 관리되고 사용하기 쉬운 양식 라이브러리로 추천합니다. 최적의 성능을 위해 제어되지 않는 형식을 취하는 동시에 반응형 렌더링을 위한 단일 입력을 볼 수 있습니다.

Redux, React context 또는 기타 상태 관리 시스템을 사용하든 올바르게 구현한다는 가정하에 일반적으로 성능 측면에서는 차이가 없습니다.flux 아키텍처가 마음에 든다면 반드시 Redux를 사용하세요. 하지만 대부분의 경우 React 컨텍스트는 성능이 뛰어나고 충분합니다.

귀하의useInput自定义挂钩看起来是解决问题react-hook-formreact-final-form용감하지만 잘못된 코드 시도가 해결되었습니다. 이 추상화로 인해 불필요한 복잡성과 예측할 수 없는부작용이 발생하고 있습니다. 또한 React에서 종종 안티 패턴이 되는mirror props a>를 사용합니다.

정말로 자신만의 양식 논리를 구현하고 싶다면(교육 목적이 아닌 한 권장하지 않음) 다음 지침을 따르세요.

  1. 가장 높은 공통 조상에서 단일 진실 소스를 유지하세요
  2. 상태 미러링 및 복사를 피하세요
  3. useMemouseRef를 사용하여 가능한 한 적게 다시 렌더링하세요
    P粉596191963

    이것은 Redux와 같은 게시-구독 라이브러리와 구성 요소 트리를 통한 상태 전파 사이를 결정하는 데 사용하는 간단한 측면입니다.

    두 구성요소가 상위-하위 관계를 갖고 최대 두 개의 가장자리가 서로 떨어져 있는 경우 하위 상태를 상위로 전파합니다.

    부모 -> child1-level1 -> child1-level2 ------ OK

    부모 -> child1-level1 ------ 확인

    부모 -> child1-level1 -> child1-level2 -> child1-level3 --> child1-level3에서 부모로 상태를 변경하기에는 이동이 너무 많습니다

    • 대화형 구성 요소 사이의 거리가 2개 이상의 가장자리인 경우 redux를 사용하세요
    • 형제 구성 요소, 즉 상위 구성 요소를 공유하고 서로 통신해야 하는 하위 구성 요소에 redux를 사용합니다(측면 패널에서 트리 항목을 선택하고 기본 구성 요소에서 선택한 항목의 세부 정보 표시)

    구현 이후

    • useInput이 과도한 리팩토링이라고 생각합니다. 입력 구성 요소는 입력 관련 작업, 더 나은 추상 유효성 검사 등을 관리하는 데 충분해야 합니다.
    • 양식 제출 시 모든 유효성 검사를 트리거할 수 있으며, 이 경우 제어된 입력이 필요하지 않습니다(양식의 onSubmit 이벤트에 유효성 검사 추가)
    • 그러나 양식에 너무 많은 필드(예: 5개 이상)가 포함되어 있고 제출하기 전에 필드의 유효성을 검사하려는 경우 입력 필드의 onBlur 이벤트를 사용하거나 디바운스 작업(예: lodash의 디바운스 작업)과 함께 onInput을 사용할 수 있습니다. 아니면 이렇게 구현하세요

    으아악
      최신 다운로드
      더>
      웹 효과
      웹사이트 소스 코드
      웹사이트 자료
      프론트엔드 템플릿
      회사 소개 부인 성명 Sitemap
      PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!