작은 반응 팁 – 사용자 정의 가능한 필터 패널 구성 요소
12800 단어 react
데이터 테이블의 종류에 따라 날짜, 가격, 이름 또는 시스템에 있는 항목의 ID로 테이블을 필터링할 수 있습니다. 다른 테이블에는 다른 열 집합이 있으므로 다른 필터를 가질 수 있습니다.
우리는 상태를 로컬로 유지하고 새로운 유형의 필터 필드를 추가하는 기능을 제공하는 재사용 가능하고 사용자 정의 가능한 솔루션을 원했습니다.
다음과 같은 직접적인 솔루션을 사용할 수 있습니다.
function FilterPanel(props) {
...
return pug`
if props.hasDate
FieldDate(
value=...
onChange=...
)
if props.hasAmount
FieldAmount(
value=...
onChange=...
)
...
`
}
그리고 여기에서 볼 수 있듯이
hasDate , hasAmount 와 같은 플래그로 필드의 존재를 제어합니다. 이는 필드의 순서를 변경하려는 경우 유연하지 않습니다. 그런 다음 우리는 필드와 패널을 분리하기로 결정했습니다.더 나은 솔루션을 찾기 위한 첫 번째 단계는 인터페이스 초안을 작성하여 우리가 사용하려는 방식을 설명하는 것이었습니다. 우리는 다음을 생각해 냈습니다.
FilterPanel(
values={}
onApply=(() => {})
)
FieldGroup
FieldDate(
name="dateMin"
)
FieldDate(
name="dateMax"
)
FieldGroup
FieldAmount(
name="amountMin"
)
FieldAmount(
name="amountMax"
)
여기에서 볼 수 있듯이 패널을 사용할 테이블에 따라 패널을 구성할 수 있습니다.
이러한 필드 간에 논리를 공유하고 필드를 그룹화하려는 경우에 유연하게 만들기 위해 React Context를 사용했습니다.
새롭다면 official docs을 먼저 읽는 것이 좋습니다.
이 구성 요소에 대해 다음 폴더 구조를 만듭니다.
FilterPanel/
Context/
FieldDate/
FieldAmount/
FieldName/
atoms.common.js <--- common styled components
atoms.js
index.js
컨텍스트 모듈부터 시작하겠습니다.
import { createContext, useContext } from 'react'
const Context = createContext({
getValue: () => null,
setValue: () => {},
})
Context.displayName = 'FilterPanelContext'
export const Provider = Context.Provider
export function useFilterPanelContext() {
return useContext(Context)
}
이것은 컨텍스트 인스턴스와 함께 작동하는 인터페이스인 Provider 구성 요소 및 useFilterPanelContext입니다.
상태 유지는 FilterPanel 구성 요소로 이동했습니다.
function FilterPanel(props) {
const [values, setValues] = useState(props.values)
const [wasChanged, setWasChanged] = useState(false)
const isApplied = !_.isEmpty(props.values)
function getValue(name) {
return values[name]
}
function setValue(name, value) {
setWasChanged(true)
setValues({ ...values, [name]: value })
}
function clearValues() {
setWasChanged(false)
setValues({})
props.onApply({})
}
function submitValues(event) {
event.preventDefault()
setWasChanged(false)
props.onApply(values)
}
const formLogic = {
getValue,
setValue,
}
return pug`
form(onSubmit=submitValues)
Provider(value=formLogic)
Wrapper
each child in Children.toArray(props.children)
Box(mr=1.5)
= child
Box(mr=1.2)
if isApplied && !wasChanged
Button(
type="button"
variant="outlined"
size="medium"
onClick=clearValues
) Clear
else
Button(
type="submit"
variant="outlined"
size="medium"
) Filter
`
}
코드는 최고의 문서입니다. 그리고 더 알고 싶은 장소가 있다면 여기에 몇 가지 설명이 있습니다.
왜 우리는 국지적으로 국가를 유지합니까? 필터가 변경된 직후에 이 필터를 적용하지 않기를 원합니다. "필터"버튼을 클릭해야만 적용됩니다.
추적하는 이유는 무엇입니까
wasChanged? 사용자가 필드 값을 변경했는지 알고 싶기 때문에 "지우기"버튼 대신 "필터"버튼을 다시 표시합니다.Provider가 우리에게 어떤 도움이 됩니까? value 소품으로 전달된 데이터는 이제 useFilterPanelContext 후크를 사용하는 모든 구성 요소에서 사용할 수 있습니다.Children.toArray(props.children)의 목적은 무엇입니까? 자식을 렌더링하고 몇 가지 추가 논리를 적용하는 방법입니다. 여기에서 각 자식을 Box — 여백 오른쪽을 추가하는 구성요소로 래핑합니다.마지막으로 중요한 것은 필드 구성 요소입니다. 금액 1을 예로 들겠습니다. 여기있어:
function FilterPanelFieldAmount(props) {
const { getValue, setValue } = useFilterPanelContext() <---- our hook
const handleChange = event => setValue(event.target.name, event.target.value)
const handleClear = () => setValue(props.name, '')
const value = getValue(props.name)
const Icon = pug`
if value
IconButton(
variant="icon"
size="small"
type="button"
onClick=handleClear
)
Icons.TimesCircle
else
IconLabel(for=props.name)
Icons.AmountFilter
`
return pug`
FieldText(
size="medium"
id=props.name
name=props.name
value=value
placeholder=props.placeholder
onChange=handleChange
endAdornment=Icon
)
`
}
그리고 그게 다야! React Context를 통해 사용자 정의할 수 있는 것을 만드는 것은 정말 좋은 방법입니다. 도움이 되었기를 바라며 제가 놓친 부분이 있으면 알려주세요.
건배!
Reference
이 문제에 관하여(작은 반응 팁 – 사용자 정의 가능한 필터 패널 구성 요소), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/viscoze/small-react-tip-customisable-filter-panel-component-4klb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)