작은 반응 팁 – 사용자 정의 가능한 필터 패널 구성 요소
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.)