[英]Multiple checkbox filtering in React
I'm struggling to create multiple Checkbox filtering in React with Material-UI.我正在努力使用 Material-UI 在 React 中创建多个复选框过滤。 The difficult is that checkbox options are created dynamically from received data and should be split by each type of Select components
困难在于复选框选项是根据接收到的数据动态创建的,并且应该由每种类型的 Select 组件拆分
But I can't properly create states to manage them in the App.但我无法在 App 中正确创建状态来管理它们。
Any ideas how to do it correctly?任何想法如何正确地做到这一点?
Options Component选项组件
function filterDuplicate(arr) {
return arr.filter((elem, index, array) => array.indexOf(elem) === index);
}
export default function Options({ stat }) {
const [form, setForm] = useState({
publicationType: "",
termType: "",
reportGroup: "",
reportState: "",
reportFormat: ""
});
const publicationTypes = filterDuplicate(
stat.map((data) => data.publicationType)
);
const termTypes = filterDuplicate(stat.map((data) => data.termType));
const reportGroups = filterDuplicate(stat.map((data) => data.reportGroup));
const reportStates = filterDuplicate(stat.map((data) => data.reportState));
const reportFormats = filterDuplicate(stat.map((data) => data.reportFormat));
function handleSubmit(e) {
e.preventDefault();
console.log(form);
}
return (
<>
<form onSubmit={handleSubmit} className="options">
<Select type="Publication type" options={publicationTypes} />
<Select type="Term type" options={termTypes} />
<Select type="Report group" options={reportGroups} />
<Select type="Status" options={reportStates} />
<Select type="File Type" options={reportFormats} />
<Button variant="contained" color="secondary" type="submit">
RESET
</Button>
</form>
</>
);
}
Options.propTypes = {
stat: PropTypes.arrayOf(PropTypes.shape({})).isRequired
};
Select Component Select 组件
export default function Select({ type, options }) {
const [check, setCheck] = useState([]);
const [value, setValue] = useState("");
const classes = useStyles();
const handleChange = (e) => {
if (e.target.checked) {
setCheck([...check, e.target.value]);
} else {
setCheck(check.filter((id) => id !== e.target.value));
}
const str = check.join(", ");
setValue(str);
};
return (
<>
<FormControl className={classes.formControl}>
<InputLabel id="select-label" className={classes.label}>
{type}
</InputLabel>
<MaterialSelect labelId="select-label" id="input-select">
{options.map((option) => (
<Checkbox option={option} key={option} onChange={handleChange} />
))}
</MaterialSelect>
</FormControl>
</>
);
}
Checkbox Component复选框组件
const Checkbox = React.forwardRef(({ option, onChange }, ref) => {
return (
<div ref={ref}>
<FormControlLabel
control={<MaterialCheckbox onChange={onChange} color="primary" />}
label={option}
value={option}
/>
</div>
);
});
Checkbox.propTypes = {
option: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired
};
export default Checkbox;
https://codesandbox.io/s/checkbox-filter-vqex7?file=/src/Options.js:0-1593 https://codesandbox.io/s/checkbox-filter-vqex7?file=/src/Options.js:0-1593
The problem is you only pass data from parent to child.问题是您只将数据从父母传递给孩子。 On App.js they are two separate components.
在 App.js 上,它们是两个独立的组件。 You should write a function on App.js that connects these two components.
您应该在连接这两个组件的 App.js 上编写 function。
Your App.js你的 App.js
export default function App() {
const [stat, setState] = useState([]);
useEffect(() => {
setState(data);
}, []);
return (
<div className="App">
<div>
<div>
<h1>Information</h1>
</div>
<Options stat={stat} />
<Data info={stat} />
</div>
</div>
);
}
App.js when filtering method added添加过滤方法时的 App.js
export default function App() {
const [stat, setState] = useState([]);
useEffect(() => {
setState(data);
}, []);
const handleFilter = (selectedValue) => {
console.log(selectedValue);
//apply filtering here and setState again
}
return (
<div className="App">
<div>
<div>
<h1>Information</h1>
</div>
<Options stat={stat} handleFilter={handleFilter} />
<Data info={stat} />
</div>
</div>
);
}
Options.js选项.js
export default function Options({ stat, handleFilter }) {
const [form, setForm] = useState({
publicationType: "",
termType: "",
reportGroup: "",
reportState: "",
reportFormat: ""
});
const publicationTypes = filterDuplicate(
stat.map((data) => data.publicationType)
);
const termTypes = filterDuplicate(stat.map((data) => data.termType));
const reportGroups = filterDuplicate(stat.map((data) => data.reportGroup));
const reportStates = filterDuplicate(stat.map((data) => data.reportState));
const reportFormats = filterDuplicate(stat.map((data) => data.reportFormat));
function handleSubmit(e) {
e.preventDefault();
console.log(form);
}
return (
<>
<form onSubmit={handleSubmit} className="options">
<Select
type="Publication type"
options={publicationTypes}
handleFilter={handleFilter}
/>
<Select
type="Term type"
options={termTypes}
handleFilter={handleFilter}
/>
<Select
type="Report group"
options={reportGroups}
handleFilter={handleFilter}
/>
<Select
type="Status"
options={reportStates}
handleFilter={handleFilter}
/>
<Select
type="File Type"
options={reportFormats}
handleFilter={handleFilter}
/>
<Button variant="contained" color="secondary" type="submit">
RESET
</Button>
</form>
</>
);
}
Select.js Select.js
export default function Select({ type, options, handleFilter }) {
const [check, setCheck] = useState([]);
const [value, setValue] = useState("");
const classes = useStyles();
const handleChange = (e) => {
if (e.target.checked) {
handleFilter(e.target.value);
setCheck([...check, e.target.value]);
} else {
setCheck(check.filter((id) => id !== e.target.value));
}
const str = check.join(", ");
setValue(str);
};
return (
<>
<FormControl className={classes.formControl}>
<InputLabel id="select-label" className={classes.label}>
{type}
</InputLabel>
<MaterialSelect labelId="select-label" id="input-select">
{options.map((option) => (
<Checkbox option={option} key={option} onChange={handleChange} />
))}
</MaterialSelect>
</FormControl>
</>
);
}
With that structure, you can receive checked value on App.js and filter data.使用该结构,您可以在 App.js 上接收检查值并过滤数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.