我对反应有点陌生,在这种情况下,我为React中的表实现自定义下拉过滤器。我为每列设置了下拉值,并且有一个“应用”按钮。
为此,我维护了一个子组件,该组件接收下拉值并将选定的组件返回给父组件。然后,我调用一个后端API,该API向我提供过滤后的数据,这些数据依次设置了父状态。问题是我获取数据并设置父状态后,下拉列表中的复选框值丢失了。
我不明白为什么我会丢失复选框值?
如果有人可以帮助我,这将有很大帮助
我正在做类似的事情:代码沙箱:https://codesandbox.io/s/quizzical-glitter-np8iw
import * as React from "react";
import { render } from "react-dom";
import ReactTable from "react-table";
import "./styles.css";
import "react-table/react-table.css";
import Child from "./Child";
interface IState {
data: {}[];
columns: {}[];
selectedValues: {};
}
interface IProps {}
export default class App extends React.Component<IProps, IState> {
constructor(props) {
super(props);
this.state = {
data: [
{ firstName: "Jack", status: "Submitted", age: "14" },
{ firstName: "Simon", status: "Pending", age: "15" },
{ firstName: "Pete", status: "Approved", age: "16" },
{ firstName: "Lucas", status: "Rejected", age: "19" }
],
selectedValues: {},
columns: []
};
}
getValuesFromKey = (data, key) => {
return data.map(item => item[key]);
};
handleFilter = (fieldName: any, selectedValue: any) => {
this.setState(
{
selectedValues: {
...this.state.selectedValues,
[fieldName]: selectedValue
}
},
() => this.handleColumnFilter(this.state.selectedValues)
);
};
handleColumnFilter = (values: any) => {
// Here I make a backend API call that gives me filtered data and then I set the tables data.
// this.setState({data: filteredDataFromServer});
// I lose the checkbox values here
};
componentDidMount() {
let columns = [
{
Header: () => (
<div>
<div style={{ position: "absolute", marginLeft: "10px" }}>
<Child
key="firstName"
name="firstName"
options={this.getValuesFromKey(this.state.data, "firstName")}
handleFilter={this.handleFilter}
/>
</div>
<span>First Name</span>
</div>
),
accessor: "firstName",
sortable: false,
show: true,
displayValue: " First Name"
},
{
Header: () => (
<div>
<div style={{ position: "absolute", marginLeft: "10px" }}>
<Child
key="status"
name="status"
options={this.getValuesFromKey(this.state.data, "status")}
handleFilter={this.handleFilter}
/>
</div>
<span>Status</span>
</div>
),
accessor: "status",
sortable: false
},
{
Header: "Age",
accessor: "age"
}
];
this.setState({ columns });
}
render() {
const { data, columns } = this.state;
return (
<div>
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
className="-striped -highlight"
/>
</div>
);
}
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
import * as React from "react";
import { Button, Checkbox, Icon } from "semantic-ui-react";
import "./styles.css";
interface IProps {
options: any;
name: string;
handleFilter(val1: any, val2: any): void;
}
interface IState {
showList: boolean;
selected: [];
}
export default class Child extends React.Component<IProps, IState> {
constructor(props) {
super(props);
this.state = {
selected: [],
showList: false
};
}
handleValueChange = (event: React.FormEvent<HTMLInputElement>, data: any) => {
let updated: any;
if (data.checked) {
updated = [...this.state.selected, data.name];
} else {
updated = this.state.selected.filter(v => v !== data.name);
}
this.setState({ selected: updated });
};
passSelectionToParent = (event: any) => {
event.preventDefault();
// I am sending the selected column name and corresponding checked values to parent
this.props.handleFilter(this.props.name, this.state.selected);
};
toggleList = () => {
this.setState(prevState => ({ showList: !prevState.showList }));
};
render() {
let { showList } = this.state;
let visibleFlag: string;
if (showList === true) visibleFlag = "visible";
else visibleFlag = "";
return (
<div>
<div style={{ position: "absolute" }}>
<div
className={"ui scrolling dropdown column-settings " + visibleFlag}
>
<Icon className="filter" onClick={this.toggleList} />
<div className={"menu transition " + visibleFlag}>
<div className="menu-item-holder">
{this.props.options.map((item: any, i: number) => (
<div className="menu-item" key={i}>
<Checkbox
name={item}
onChange={this.handleValueChange}
label={item}
/>
</div>
))}
</div>
<div className="menu-btn-holder">
<Button size="small" onClick={this.passSelectionToParent}>
Apply
</Button>
</div>
</div>
</div>
</div>
</div>
);
}
}