javascript 使用按钮在 React 中的 react-table 上触发过滤器功能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48630384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use Buttons to trigger filter function on react-table in React
提问by donlaur
I don't know how to word this. I am learning React and I have data loaded into React-Table via fetch. I tried using React-Table and just custom plain divs and tables.
我不知道怎么说这个。我正在学习 React,并且通过 fetch 将数据加载到 React-Table 中。我尝试使用 React-Table 和自定义的普通 div 和表格。
I want to create a touch buttons of the alphabet from A, B, C, D ... Z. Those buttons should call the filter for the letter that is in the button. So, for example the buttons are the following.
我想从 A、B、C、D ... Z 创建一个字母触摸按钮。这些按钮应该为按钮中的字母调用过滤器。因此,例如按钮如下。
// In Directory.js
class FilterButtons extends React.Component {
alphaFilter(e) {
console.log(e.target.id);
// somehow filter the react table
}
render() {
return (
<div>
<button onClick={this.alphaFilter} id="A" className="letter">A</button>
<button onClick={this.alphaFilter} id="B" className="letter">B</button>
<button onClick={this.alphaFilter} id="C" className="letter">C</button>
</div>
);
}
}
const BottomMenu = props => (
<div className="btm-menu">
<div className="toprow">
<div className="filter-keys">
<FilterButtons />
</div>
</div>
</div>
);
// I have a class Directory extends Component that has the BottomMenu in it
// 我有一个类 Directory extends Component,其中包含 BottomMenu
// I also have a DataGrid.js with the React Table in there
// 我还有一个带有 React Table 的 DataGrid.js
class DataGrid extends React.Component {
constructor() {
super();
this.state = {
data: [],
};
}
componentWillMount() {
fetch('http://localhost:3000/rooms.json').then((results) => results.json()).then((data) => {
console.log(data.room);
this.setState({
data: data.room
})
})
}
render() {
const { data } = this.state;
return (
<div>
<ReactTable
data={data}
filterable
defaultFilterMethod={(filter, row) =>
String(row[filter.id]) === filter.value}
columns={[
{
Header: "Name",
accessor: "dName",
filterMethod: (filter, row) =>
row[filter.id].startsWith(filter.value)
},
{
Header: "Department",
accessor: "dDept"
},
{
Header: "Room",
accessor: "dRoom"
},
{
Header: "Map",
accessor: "dRoom",
id: "over",
}
]
}
defaultPageSize={14}
className="-striped -highlight"
/>
<br />
</div>
);
}
}
export default DataGrid;
At this point I am unsure what to do to get the button click of one of the A, B, C letters to filter the React Table. I do not want the Input field option that is always used because I want only buttons as the user will not have a keyboard, only touch.
在这一点上,我不确定如何点击 A、B、C 字母之一的按钮来过滤 React 表。我不想要总是使用的输入字段选项,因为我只想要按钮,因为用户没有键盘,只有触摸。
Basically, React Table or just any table that can be filtered by clicking buttons with a letter that gets passed back to the filter. If I was using JQuery I would use a button click and then filter that way. I still haven't learned all the ins and outs of React and how to get this done. I also want to use external buttons to sort but that should be easier, hopefully.
基本上,React Table 或任何可以通过单击带有传递回过滤器的字母的按钮来过滤的表。如果我使用 JQuery,我会使用按钮单击,然后以这种方式过滤。我仍然没有了解 React 的所有来龙去脉以及如何完成它。我也想使用外部按钮进行排序,但希望这应该更容易。
Thanks. Sorry if all of this doesn't make sense, I am just trying to lay it out. Again, no keyboard, only touch on a touch screen so the input field isn't going to work for me.
谢谢。对不起,如果所有这些都没有意义,我只是想把它摆出来。同样,没有键盘,只能触摸触摸屏,因此输入字段对我不起作用。
采纳答案by mcku
For React-Table filter to be controlled externally by buttons, you should take a look at the Controlled Tableexample. Then the table component becomes a controlled component.
对于要通过按钮从外部控制的 React-Table 过滤器,您应该查看受控表示例。然后 table 组件成为受控组件。
There, you can set the state of the table filter externally and use both of the props:
在那里,您可以在外部设置表过滤器的状态并使用两个道具:
<ReactTable ...(your other props)
filtered={this.state.filtered}
onFilteredChange={filtered => this.setState({ filtered })}
/>
The filteredprop will monitor change in the state. So whenever you update its value through your letter buttons via e.g.
该filtered道具将监控状态的变化。所以每当你通过你的字母按钮更新它的值时,例如
this.setState({filtered: { id: "dName", value: "A"}})
the table's filter will get updated. Also, onFilteredChange should work the other direction, namely the embedded filtering of the react-table can update the local state. So that you can monitor it and use its value within your DataGrid component.
表格的过滤器将得到更新。此外, onFilteredChange 应该在另一个方向上工作,即 react-table 的嵌入式过滤可以更新本地状态。这样您就可以监视它并在 DataGrid 组件中使用它的值。
One other option could be to avoid using local states and implement it in redux, though. Because states hanging around components are eventually becoming source of errors and increasing complexity of debugging.
不过,另一种选择可能是避免使用本地状态并在 redux 中实现它。因为组件周围的状态最终会成为错误的来源并增加调试的复杂性。
UPDATE -- As per the question owner's comment for more details:
更新 - 根据问题所有者的评论了解更多详细信息:
In order to use FilterButtons and DataGrid together, you can define a container component that encapsulates both FilterButtons and DataGrid. The container component keeps the shared state, and the filtering function operates on the state function. But data will still reside within the datagrid.
为了同时使用FilterButtons 和DataGrid,您可以定义一个封装FilterButtons 和DataGrid 的容器组件。容器组件保持共享状态,过滤函数对状态函数进行操作。但数据仍将驻留在数据网格中。
class DataGridWithFilter extends React.Component {
// you need constructor() for binding alphaFilter to this.
// otherwise it cannot call this.setState
constructor(props) {
super(props);
this.alphaFilter = this.alphaFilter.bind(this);
}
// personally i do not use ids for passing data.
// therefore introduced the l parameter for the letter
alphaFilter(e,l) {
console.log(e.target.id);
this.setState({filtered: { id: "dName", value: l}});
}
render(){
return <div>
<DataGrid filtered={this.state.filtered}
filterFunc={this.alphaFilter}
</DataGrid>
<BottomMenu filtered={this.state.filtered}
filterFunc={this.alphaFilter} />
</div>
}
}
Also this above thing requires the use of prop filterFuncfrom within BottomMenu and FilterButtons components.
此外,上面的内容需要filterFunc在 BottomMenu 和 FilterButtons 组件中使用 prop 。
class FilterButtons extends React.Component {
render() {
const {props} = this;
return (
<div>
<button onClick={(e) => props.filterFunc(e, "A")} id="A" className="letter">A</button>
<button onClick={(e) => props.filterFunc(e, "B")} id="B" className="letter">B</button>
<button onClick={(e) => props.filterFunc(e, "C")} id="C" className="letter">C</button>
</div>
);
}
}
const BottomMenu = props => (
<div className="btm-menu">
<div className="toprow">
<div className="filter-keys">
<FilterButtons filterFunc = {props.filterFunc} />
</div>
</div>
</div>
);
class DataGrid extends React.Component {
constructor() {
super();
this.state = {
data: [],
};
}
componentWillMount() {
fetch('http://localhost:3000/rooms.json').then((results) => results.json()).then((data) => {
console.log(data.room);
this.setState({
data: data.room
})
})
}
render() {
const { data } = this.state;
return (
<div>
<ReactTable
data={data}
filterable
defaultFilterMethod={(filter, row) =>
String(row[filter.id]) === filter.value}
columns={[
{
Header: "Name",
accessor: "dName",
filterMethod: (filter, row) =>
row[filter.id].startsWith(filter.value)
},
{
Header: "Department",
accessor: "dDept"
},
{
Header: "Room",
accessor: "dRoom"
},
{
Header: "Map",
accessor: "dRoom",
id: "over",
}
]
}
defaultPageSize={14}
className="-striped -highlight"
filtered = {this.props.filtered}
onFilteredChange = {filtered => this.props.filterFunc({filtered})}
/>
<br />
</div>
);
}
}
I have not checked against typo etc but this should work.
我没有检查错字等,但这应该有效。
回答by Khun
In React, you can update components when state changes. The only way to trigger is to use this.setState()
在 React 中,您可以在状态更改时更新组件。触发的唯一方法是使用 this.setState()
So I would change my state object something like this:
所以我会像这样改变我的状态对象:
state = {
date: [],
filter: ""
};
so here is the new file:
所以这是新文件:
// In Directory.js
class FilterButtons extends React.Component {
alphaFilter = (word) => {
this.setState({
filter: word
});
};
render() {
return (
<div>
<button onClick={() => this.alphaFilter("A")} id="A" className="letter">A</button>
<button onClick={() => this.alphaFilter("B")} id="B" className="letter">B</button>
<button onClick={() => this.alphaFilter("C")} id="C" className="letter">C</button>
</div>
);
}
}
const BottomMenu = props => (
<div className="btm-menu">
<div className="toprow">
<div className="filter-keys">
<FilterButtons />
</div>
</div>
</div>
);
right after you call alphaFilter()your component will update. And when you put your filter function in it it's going display as expected. So I would choose the .map()function of array. You can either use filter()or return after comparing data in map()
在您调用alphaFilter()您的组件后立即更新。当您将过滤器功能放入其中时,它会按预期显示。所以我会选择.map()数组的功能。您可以filter()在比较数据后使用或返回map()

