저는 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() { 탐색('/가입'); } 반품 (); } 기본 로그인 페이지 내보내기;바둑컵바둑컵 계정에 로그인하세요
<카드 테두리>
위 코드에서 볼 수 있듯이 FormGroup 구성 요소를 사용하고 onValidityChange
및 onReset
속성을 전달하여 isValid< /코드의 업데이트된 값> 양식 제출 등 이후 입력 내용을 재설정하는 변경 및 재설정 기능 내 사용자 정의 후크 useInput을 사용하여 입력 구성 요소에
isValid
및 reset
값이 변경되면 isValid 값을 전달하고 FormGroup 구성 요소에 정의된 props를 사용하여 입력 구성 요소에서 재설정 함수를 전달합니다. 또한 로그인 페이지에서 isLoginValid
및 isPasswordValid
상태를 사용하여 하위 입력에서 전달된 업데이트된 isValid
요소. 그래서 입력 컴포넌트에 상태를 정의하고 props를 사용하여 이를 부모 컴포넌트에 전달하고 그 값을 해당 부모 컴포넌트에서 생성된 다른 상태에 저장했습니다. 진행되고 있는 소품 드릴링이 조금 불편했습니다.
상태는 입력 구성 요소 내부에서 관리되며 다음과 같은 상태를 갖습니다.
일부 기능(예: 입력 구성 요소에 전달된 유효성 검사 기능)을 이 두 상태에 결합하고 적용하여 다른 변수 값을 생성하여 입력 및 해당 값의 유효성(예: 값이 유효한지 여부)에 대한 정보를 수집합니다. (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
, isValid
및 reset
함수도 상위 구성 요소에 전달합니다. 그것에 사용합니다. 이러한 상태와 함수를 전달하기 위해 소품에 정의된 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를 처음 접하기 때문에 단순한 실수부터 일반적인 실수까지 모든 코딩에 대한 여러분의 제안에 열려 있습니다. 감사해요!
React의 상태 관리에는 제어된 상태와 제어되지 않은 상태라는 두 가지 주요 사고 방식이 있습니다. 제어된 양식은 반응성을 제공하기 위해 어디에서나 값에 액세스할 수 있는 React 컨텍스트를 사용하여 제어할 수 있습니다. 그러나 제어된 입력은 특히 각 입력에서 전체 양식을 업데이트할 때 성능 문제를 일으킬 수 있습니다. 통제되지 않은 형태가 등장하는 곳입니다. 이 패러다임을 사용하면 모든 상태 관리는 상태 표시를 위한 브라우저의 기본 기능을 활용해야 합니다. 이 접근 방식의 주요 문제점은 양식의 React 측면을 잃어버리고 제출 시 양식 데이터를 수동으로 수집해야 하며 이에 대한 여러 참조를 유지하는 것이 지루할 수 있다는 것입니다.
제어된 입력은 다음과 같습니다.
으아악EDIT: @Arkellys가 지적했듯이 양식 데이터를 수집하기 위해 반드시 참조가 필요한 것은 아닙니다.다음은
을 사용한 예입니다.FormData
통제 불능:
으아악두 가지 접근 방식 중 하나를 사용하여 다중 구성 요소 양식을 유지하는 것은 지루하다는 것이 두 예에서 명백하므로 양식 관리를 돕기 위해 라이브러리가 자주 사용됩니다. 저는 개인적으로React Hook Form을 철저한 테스트를 거쳐 잘 관리되고 사용하기 쉬운 양식 라이브러리로 추천합니다. 최적의 성능을 위해 제어되지 않는 형식을 취하는 동시에 반응형 렌더링을 위한 단일 입력을 볼 수 있습니다.
Redux, React context 또는 기타 상태 관리 시스템을 사용하든 올바르게 구현한다는 가정하에 일반적으로 성능 측면에서는 차이가 없습니다.flux 아키텍처가 마음에 든다면 반드시 Redux를 사용하세요. 하지만 대부분의 경우 React 컨텍스트는 성능이 뛰어나고 충분합니다.
귀하의
useInput
自定义挂钩看起来是解决问题react-hook-form
和react-final-form
용감하지만 잘못된 코드 시도가 해결되었습니다. 이 추상화로 인해 불필요한 복잡성과 예측할 수 없는부작용이 발생하고 있습니다. 또한 React에서 종종 안티 패턴이 되는mirror props a>를 사용합니다.정말로 자신만의 양식 논리를 구현하고 싶다면(교육 목적이 아닌 한 권장하지 않음) 다음 지침을 따르세요.
useMemo
和useRef
를 사용하여 가능한 한 적게 다시 렌더링하세요이것은 Redux와 같은 게시-구독 라이브러리와 구성 요소 트리를 통한 상태 전파 사이를 결정하는 데 사용하는 간단한 측면입니다.
두 구성요소가 상위-하위 관계를 갖고 최대 두 개의 가장자리가 서로 떨어져 있는 경우 하위 상태를 상위로 전파합니다.
부모 -> child1-level1 -> child1-level2 ------ OK
부모 -> child1-level1 ------ 확인
부모 -> child1-level1 -> child1-level2 -> child1-level3 --> child1-level3에서 부모로 상태를 변경하기에는 이동이 너무 많습니다
구현 이후