개체 설정을 사용하여 태그 필드 만들기
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.)