在 React 中使用 Buttons 在 react-table 上触发过滤功能
Use Buttons to trigger filter function on react-table in React
我不知道怎么说。我正在学习 React,我已经通过 fetch 将数据加载到 React-Table 中。我尝试使用 React-Table 并仅自定义普通 div 和 tables.
我想创建一个 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>
);
// 我有一个 class 目录扩展组件,里面有 BottomMenu
// 我也有一个 DataGrid.js 里面有 React Table
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;
此时我不确定如何点击 A、B、C 字母之一的按钮来过滤 React Table。我不想要始终使用的输入字段选项,因为我只想要按钮,因为用户没有键盘,只有触摸。
基本上,React Table 或任何 table 都可以通过单击带有传递回过滤器的字母的按钮来过滤。如果我使用 JQuery,我会使用按钮单击,然后以这种方式进行过滤。我仍然没有了解 React 的所有细节以及如何完成它。我也想使用外部按钮进行排序,但希望这样更容易。
谢谢。
对不起,如果所有这些都没有意义,我只是想把它摆出来。同样,没有键盘,只能触摸触摸屏,所以输入字段对我不起作用。
在 React 中,您可以在状态更改时更新组件。触发的唯一方法是使用 this.setState()
所以我会像这样更改我的状态对象:
state = {
date: [],
filter: ""
};
所以这是新文件:
// 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>
);
在您调用 alphaFilter()
后您的组件将立即更新。当您将过滤器功能放入其中时,它会按预期显示。所以我会选择数组的.map()
函数。比较 map()
中的数据后,您可以使用 filter()
或 return
对于 React-Table 由按钮外部控制的过滤器,你应该看看 Controlled Table example. Then the table component becomes a controlled component.
在那里,您可以在外部设置 table 过滤器的状态并使用两个道具:
<ReactTable ...(your other props)
filtered={this.state.filtered}
onFilteredChange={filtered => this.setState({ filtered })}
/>
filtered
属性将监视状态的变化。因此,每当您通过字母按钮更新其值时,例如
this.setState({filtered: { id: "dName", value: "A"}})
table 的过滤器将得到更新。此外,onFilteredChange 应该在另一个方向上工作,即 react-table 的嵌入式过滤可以更新本地状态。这样您就可以监视它并在您的 DataGrid 组件中使用它的值。
另一种选择是避免使用本地状态并在 redux 中实现它。因为组件周围的状态最终会成为错误的来源并增加调试的复杂性。
更新——根据问题所有者的评论了解更多详情:
为了同时使用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>
}
}
此外,上述内容需要使用 BottomMenu 和 FilterButtons 组件中的道具 filterFunc
。
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>
);
}
}
我没有检查拼写错误等,但这应该有效。
对于react-table 7 你可以监听外部的输入变化并调用setFilter
:
useEffect(() => {
// This will now use our custom filter for age
setFilter("age", ageOutside);
}, [ageOutside]);
见https://codesandbox.io/s/react-table-filter-outside-table-bor4f?file=/src/App.js
我不知道怎么说。我正在学习 React,我已经通过 fetch 将数据加载到 React-Table 中。我尝试使用 React-Table 并仅自定义普通 div 和 tables.
我想创建一个 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>
);
// 我有一个 class 目录扩展组件,里面有 BottomMenu
// 我也有一个 DataGrid.js 里面有 React Table
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;
此时我不确定如何点击 A、B、C 字母之一的按钮来过滤 React Table。我不想要始终使用的输入字段选项,因为我只想要按钮,因为用户没有键盘,只有触摸。
基本上,React Table 或任何 table 都可以通过单击带有传递回过滤器的字母的按钮来过滤。如果我使用 JQuery,我会使用按钮单击,然后以这种方式进行过滤。我仍然没有了解 React 的所有细节以及如何完成它。我也想使用外部按钮进行排序,但希望这样更容易。
谢谢。 对不起,如果所有这些都没有意义,我只是想把它摆出来。同样,没有键盘,只能触摸触摸屏,所以输入字段对我不起作用。
在 React 中,您可以在状态更改时更新组件。触发的唯一方法是使用 this.setState()
所以我会像这样更改我的状态对象:
state = {
date: [],
filter: ""
};
所以这是新文件:
// 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>
);
在您调用 alphaFilter()
后您的组件将立即更新。当您将过滤器功能放入其中时,它会按预期显示。所以我会选择数组的.map()
函数。比较 map()
filter()
或 return
对于 React-Table 由按钮外部控制的过滤器,你应该看看 Controlled Table example. Then the table component becomes a controlled component.
在那里,您可以在外部设置 table 过滤器的状态并使用两个道具:
<ReactTable ...(your other props)
filtered={this.state.filtered}
onFilteredChange={filtered => this.setState({ filtered })}
/>
filtered
属性将监视状态的变化。因此,每当您通过字母按钮更新其值时,例如
this.setState({filtered: { id: "dName", value: "A"}})
table 的过滤器将得到更新。此外,onFilteredChange 应该在另一个方向上工作,即 react-table 的嵌入式过滤可以更新本地状态。这样您就可以监视它并在您的 DataGrid 组件中使用它的值。
另一种选择是避免使用本地状态并在 redux 中实现它。因为组件周围的状态最终会成为错误的来源并增加调试的复杂性。
更新——根据问题所有者的评论了解更多详情:
为了同时使用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>
}
}
此外,上述内容需要使用 BottomMenu 和 FilterButtons 组件中的道具 filterFunc
。
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>
);
}
}
我没有检查拼写错误等,但这应该有效。
对于react-table 7 你可以监听外部的输入变化并调用setFilter
:
useEffect(() => {
// This will now use our custom filter for age
setFilter("age", ageOutside);
}, [ageOutside]);
见https://codesandbox.io/s/react-table-filter-outside-table-bor4f?file=/src/App.js