나만의 React 유효성 검사 라이브러리 만들기: 개발자 경험(3부)
게시 됨: 2022-03-10이 짧은 기사 시리즈를 따라왔다면 이제 고유한 유효성 검사 라이브러리를 구성하는 방법을 배웠습니다. 던질 수 있는 거의 모든 문제를 처리할 수 있으며 접근성 문제에도 도움이 됩니다! 그것의 유일한 단점은 작업하기가 힘들다는 것입니다.
네, 맞습니다. 개발자 관점의 사용자 경험은 심각하게 부족합니다. 우리는 단어의 철자를 틀리거나 API를 오용하거나 뭐, 정말 어떤 경우에도 유용한 경고를 받지 못합니다!
이 문서에서는 유효성 검사 라이브러리 또는 이를 위한 라이브러리의 개발자 경험을 개선하는 방법을 안내합니다.
- 1부: 기본 사항
- 2부: 기능
- 3부: 경험
시작하기
이 기사의 마지막 부분 이후로 모든 라이브러리 코드를 자체 파일로 가져왔습니다. CodeSandbox 데모를 살펴보고 무엇을 시작하는지 확인하십시오.
편의 기능
우리는 우리 라이브러리가 가장 일반적인 경우에 사용하기 위해 가능한 한 단순하기를 원합니다. 그 목표를 향해 나아가는 방법은 특정 기능에 편리한 유틸리티 기능을 추가하는 것입니다.
이러한 기능 중 하나는 양식이 유효한지, 즉 모든 오류 메시지가 null
인지 확인하는 것입니다. 이것은 일반적으로 onSubmit
핸들러에서 확인하는 것이지만 렌더링 방법에서도 유용할 수 있습니다. 구현해보자!
const isFormValid = useMemo( () => Object.values(errors).every(error => error === null), [errors] );
우리는 onSubmit
양식 핸들러와 렌더 메소드에서 이 플래그를 제공할 것입니다.
- CodeSandbox 데모 보기
쓸 수 있는 내용이 더 많지만 독자를 위한 연습으로 삼겠습니다.
개발 경고 및 불변
React의 가장 큰 기능 중 하나는 개발하는 동안 유용한 콘솔 경고가 많이 있다는 것입니다. 우리는 사용자에게도 같은 종류의 품질을 제공해야 합니다.
시작하기 위해 우리는 두 가지 함수를 만들 것입니다. 콘솔에 warning
를 기록하기 위한 경고와 오류를 던지기 위한 invariant
- 둘 다 주어진 조건이 충족되지 않는 경우입니다.
function warning(condition, message) { if (process.env.NODE_ENV === 'production' || condition) { return; } console.warn('useValidation: ' + message); } function invariant(condition, message) { if (process.env.NODE_ENV === 'production' || condition) { return; } throw new Error('useValidation: ' + message); }
오류가 라이브러리에 충돌을 일으킬 경우(또는 쓸모없게 만드는 경우) invariant
을 사용하고 나쁜 관행이나 기타 조언에 대한 warning
를 사용하려고 합니다.
경고할 때
경고 시점을 결정하는 것은 매우 중요합니다. 너무 많아 짜증이 납니다. 너무 적으면 중요한 버그가 프로덕션 환경으로 배송됩니다. 그러므로 우리는 경고에 현명해야 합니다.
우리 라이브러리는 꽤 큰 구성 객체를 수용하기 때문에 적어도 개발하는 동안 어떻게든 이것을 검증하는 것이 합리적입니다. TypeScript 또는 Flow와 같은 유형 시스템을 사용하여 해결할 수 있지만 모든 일반 JavaScript 사용자는 제외됩니다.
대신 구성에 올바른 필드가 포함되어 있는지 확인하고 관련 경고를 인쇄하는 런타임 스키마 검사기를 생성해 보겠습니다.
function validateConfigSchema(config) { if (process.env.NODE_ENV === 'production') { return; } if (typeof config === 'function') { config = config({}); } invariant( typeof config === 'object', `useValidation should be called with an object or a function returning an object. You passed a ${typeof config}.`, ); invariant( typeof config.fields === 'object', 'useValidation requires a `field` prop with an object containing the fields and their validators. Please refer to the documentation on usage: https://link.to/docs' ); invariant( Object.values(config.fields).every(field => typeof field === 'object'), 'useValidation requires that the `field` object only contains objects. It looks like yours isn\'t. Please refer to the documentation on usage: https://link.to/docs' ); warning( ['always', 'blur', 'submit', undefined].includes(config.showError), 'useValidation received an unsupported value in the `showError` prop. Valid values are "always", "blur" or "submit".' ) // And so on }
우리가 시간을 보내고 싶다면 한동안 이 일을 계속할 수 있을 것입니다. 그리고 당신은해야합니다! 앱의 개발자 경험을 향상시키는 좋은 방법입니다.

그러나 이것을 손으로 쓸 필요는 없습니다. 정말 멋진 런타임 유효성 검사를 만드는 데 도움이 될 수 있는 인기 있는 개체 스키마 유효성 검사 라이브러리 joi
의 브라우저 포트가 있습니다. 또한 이전에 언급했듯이 유형 시스템은 해당 유형 시스템을 사용하는 사용자의 컴파일 시간에 구성 오류를 잡는 데 도움이 됩니다.
유연성 허용
좋은 개발자 경험은 대부분 개발자를 방해하지 않는 것입니다. 이러한 경험을 개선할 수 있는 몇 가지 방법을 살펴보겠습니다.
충돌하는 소품 작성
첫째, prop getter는 소비자가 실수로 재정의할 수 있는 입력 및 양식에 일부 prop을 적용합니다. 대신, 충돌하는 모든 prop을 함께 구성할 prop getter에 prop 재정의 객체를 추가합시다.
getFieldProps
에서 이것을 구현하는 방법은 다음과 같습니다.
getFieldProps: (fieldName, overrides = {}) => ({ onChange: e => { const { value } = e.target; if (!config.fields[fieldName]) { return; } dispatch({ type: 'change', payload: { [fieldName]: value }, }); if (overrides.onChange) { overrides.onChange(e); } }, onBlur: e => { dispatch({ type: 'blur', payload: fieldName }); if (overrides.onBlur) { overrides.onBlur(e) } }, name: overrides.name || fieldName, value: state.values[fieldName] || '', }),
getFormProps
에서도 유사한 접근 방식을 따를 수 있습니다.
소품 드릴 방지
일부 양식은 크고 여러 구성 요소로 분할될 수 있습니다. 소비자의 드릴 소품을 트리 아래로 만드는 대신 컨텍스트를 제공해야 합니다. 이렇게 하면 아래 트리의 아무 곳에서나 사용자 정의 후크에서 반환하는 모든 항목에 액세스할 수 있습니다.
먼저 React의 createContext
메소드를 사용하여 ValidationContext를 생성해 보겠습니다.
export const ValidationContext = React.createContext({});
다음으로 대신 컨텍스트에서 useValidation
후크의 모든 값을 제공하는 ValidationProvider
구성 요소를 만들어 보겠습니다.
export const ValidationProvider = props => { const context = useValidation(props.config); return ( {props.children} ); };
export const ValidationProvider = props => { const context = useValidation(props.config); return ( {props.children} ); };
export const ValidationProvider = props => { const context = useValidation(props.config); return ( {props.children} ); };
이제 useValidation
을 직접 호출하는 대신 ValidationProvider
구성 요소에 양식을 래핑하고 useContext
후크를 사용하여 유효성 검사 소품( getFormProps
, errors
등)에 액세스할 수 있습니다. 다음과 같이 사용합니다.
Import React, { useContext } from 'react'; import { ValidationContext } from './useValidation'; function UsernameForm(props) { const { getFieldProps, errors } = useContext(ValidationContext); return ( <> <input {...getFieldProps('username')} /> {errors.username && {errors.username}></span>} </> ); }
이렇게 하면 두 세계의 장점을 모두 얻을 수 있습니다! 이러한 간단한 시나리오에 대한 간단한 후크를 얻을 수 있고 복잡한 부품에 필요한 유연성을 얻을 수 있습니다.
문서화가 핵심
내가 직접 작성하지 않은 라이브러리를 사용할 때마다 나는 훌륭한 문서를 좋아합니다. 그러나 무엇에 중점을 두어야 하며 어디에 문서화해야 합니까?
첫 번째 단계는 쉽게 사용할 수 있는 가장 기본적인 사용 예와 함께 이해하기 쉬운 README를 구성하는 것입니다. Andrew Healey는 좋은 README를 작성하는 방법에 대한 놀라운 글을 썼습니다.
사람들의 관심을 끌 수 있는 좋은 README를 만들었다면 문서 웹사이트가 좋은 생각이 될 수 있습니다. 여기에 더 심층적인 API 문서, 일반적인 사용 사례에 대한 레시피 및 좋은 'FAQ'를 넣을 수 있습니다.
문서 웹 사이트를 생성하기 위한 훌륭한 도구가 있습니다. 내가 가장 좋아하는 것은 Facebook create-react-app
docusaurus
입니다.
우리는 이 기사에서 좋은 문서를 작성하는 방법을 다루지 않을 것입니다. "문서 작성"이라는 커뮤니티까지 몇 가지 좋은 기사가 있습니다. 그들은 훌륭한 문서 작성을 시작하는 방법에 대한 훌륭한 가이드를 작성했습니다.
요약
이 기사 시리즈를 통해 우리는 꽤 괜찮은 유효성 검사 라이브러리를 만들었습니다. 매우 간단한 API, 필요할 때 사용할 수 있는 유연성, 우수한 개발자 경험 및 많은 유용한 기능이 있습니다.
우리는 단계적으로 구현하는 방법을 살펴보았고, 자신만의 라이브러리를 만드는 방법과 사람들이 사용하고 싶어하는 라이브러리를 만드는 방법에 대해 더 깊이 이해하기를 바랍니다.
여러분이 생각하는 부분과, 막히거나 이해하기 어려웠던 부분이 있다면 댓글로 알려주세요. 피드백이 조금씩 들어오면 기사를 업데이트하기 위해 최선을 다하겠습니다.
이 기사를 끝내기 위해 — 최종 버전은 다음과 같습니다.
- CodeSandbox 데모 보기
읽어 주셔서 감사합니다!