개체 설정을 사용하여 태그 필드 만들기
13485 단어 reactjavascript
태그 구성 요소 만들기
이것은 약간 간단합니다. 삭제 버튼 표시를 토글하는
readOnly 와 해당 버튼을 클릭할 때 호출되는 함수인 onRemove 의 두 가지 props를 받는 상태 비저장 구성 요소입니다. 최종 결과는 다음과 같습니다.interface TagProps {
readOnly?: boolean;
onRemove?: () => void;
}
const Tag: FC<TagProps> = ({ readOnly = false, onRemove, children }) => (
<div className="tag">
<small>{children}</small>
{!readOnly && (
<button onClick={onRemove}>
<CloseIcon />
</button>
)}
</div>
);
입력 생성
이제 재미있는 부분이 있습니다. 바로 태그 입력 자체입니다. 구성 요소는 다음을 수행해야 합니다. 모든 태그와 텍스트 필드를 렌더링하고, 특정 구분 문자가 입력될 때 새 태그를 추가하고, 중복 태그를 버리고, 선택적으로 백스페이스를 눌러 최신 태그를 제거해야 합니다. 예상되는 동작을 입력하면 상황이 훨씬 쉬워집니다(이것이 단위 테스트가 유용한 이유입니다).
기초
처음부터 시작합시다: Props.
value (기본적으로 Set의 새 인스턴스로 설정됨) 및 onChange , 구성 요소를 제어 가능하게 만들기, separator (기본적으로 "," 로 설정) 태그 추가를 트리거하는 readOnly (기본적으로 false로 설정됨).다음으로 컴포넌트 상태를 생성하겠습니다.
tags 를 제어하려면 모든 값이 고유함을 보장하기 때문에 Set이 완벽합니다. 배열도 사용할 수 있지만 반복되는 태그를 수동으로 처리해야 합니다. 다음으로 텍스트 필드를 추가해야 합니다. 최종 결과가 일반적인 입력처럼 보이기를 원하기 때문에 모든 스타일을 제거하고 대신 상위 스타일div을 지정하겠습니다.interface TagInputProps {
onChange: (value: Set<string>) => void;
value?: Set<string>;
separator?: string;
readOnly?: boolean;
}
const TagInput: FC<TagInputProps> = ({
onChange,
value = new Set(),
separator = ",",
readOnly = false
}) => {
const [tags, setTags] = useState(value);
const [inputValue, setInputValue] = useState("");
return (
<div className="tag-input">
<input
value={inputValue}
onChange={({ target }) => setInputValue(target.value)}
/>
</div>
);
};
태그 추가
상태에 태그를 효과적으로 추가하기 위해
onKeyDown 이벤트를 처리할 것입니다. 누른 키( event.key )가 구분 기호와 같고 inputValue 가 비어 있지 않으면 해당 값을 tags 에 추가합니다. 코드로 번역:const handleKeyDown = useCallback(
(event) => {
if (event.key === separator) {
event.preventDefault();
if (inputValue.trim().length > 0) {
setTags((tags) => new Set([...tags, inputValue]));
setInputValue("");
}
}
},
[separator, inputValue]
);
태그 제거
태그 삭제는 두 가지 방법으로 수행할 수 있습니다. 제거 버튼을 클릭하거나 커서가 있는 경우 백스페이스 키를 누릅니다.
텍스트 필드의 위치는 0입니다.
제거 버튼
여기에는 미스터리가 없습니다.
tags 구성 요소의 onRemove 소품으로 설정된 Tag에서 항목을 제거하는 함수를 추가하기만 하면 됩니다.onRemove={() => {
const updatedTags = new Set(tags);
updatedTags.delete(tag);
setTags((tags) => updatedTags);
}}
백스페이스 누르기
다시 한 번
handleKeyDown 를 방문합니다. 먼저 prop backspaceErase 이 true 로 설정되어 있는지 확인한 다음 Backspace가 눌렸는지, 캐럿이 위치 0에 있는지 확인합니다. 하지만 어떻게 할까요? selectionStart에서 selectionEnd 및 event.target를 사용하여 : 텍스트를 선택하지 않고 커서가 시작 부분에 있는 경우 두 속성은 모두 0 가 됩니다. 이제 handleKeyDown는 다음과 같습니다.const handleKeyDown = useCallback(
(event) => {
if (event.key === separator) {
event.preventDefault();
if (inputValue.trim().length > 0) {
setTags((tags) => new Set([...tags, inputValue]));
setInputValue("");
}
}
if (backspaceErase && event.key === "Backspace") {
const { selectionStart, selectionEnd } = event.target;
if (selectionStart === 0 && selectionEnd === 0) {
setTags((tags) => new Set([...tags].slice(0, -1)));
}
}
},
[separator, inputValue]
);
결과
음, 생각보다 쉬웠습니다. 결과는 아래 코드 샌드박스에서 볼 수 있습니다. 여기에 텍스트가 맞지 않는 경우에만 줄을 나누도록 입력 크기를 동적으로 조정하는
calcInputWidth 함수도 추가했습니다. 건배! 다음 글에서 만나요!
Reference
이 문제에 관하여(개체 설정을 사용하여 태그 필드 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hnrq/using-set-object-to-create-a-tag-field-2npp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)