9

我不知道该怎么说这个。我正在学习 React,我通过 fetch 将数据加载到 React-Table 中。我尝试使用 React-Table 和自定义普通 div 和表格。

我想从 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>
);

// 我有一个类目录扩展组件,其中包含底部菜单

// 我还有一个带有 React 表的 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; 

在这一点上,我不确定该怎么做才能让 A、B、C 字母之一的按钮单击来过滤 React 表。我不想要始终使用的输入字段选项,因为我只想要按钮,因为用户没有键盘,只有触摸。

基本上,React Table 或任何可以通过单击带有传递回过滤器的字母的按钮来过滤的表。如果我使用的是 JQuery,我会使用按钮单击,然后以这种方式过滤。我仍然没有了解 React 的所有细节以及如何完成这项工作。我也想使用外部按钮进行排序,但这应该更容易,希望如此。

谢谢。抱歉,如果所有这些都没有意义,我只是想把它摆出来。同样,没有键盘,只在触摸屏上触摸,所以输入字段对我不起作用。

4

3 回答 3

5

要通过按钮从外部控制 React-Table 过滤器,您应该查看Controlled Table示例。然后表格组件成为受控组件。

在那里,您可以在外部设置表格过滤器的状态并使用这两个道具:

<ReactTable  ...(your other props)
        filtered={this.state.filtered}
        onFilteredChange={filtered => this.setState({ filtered })}
 />

filtered道具将监视状态的变化。因此,每当您通过字母按钮更新其值时,例如

this.setState({filtered: { id: "dName", value: "A"}})

表的过滤器将得到更新。此外,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>
 }
}

此外,上述内容需要使用filterFuncBottomMenu 和 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>
    );
  }
}

我没有检查错字等,但这应该可以。

于 2018-02-07T22:45:36.480 回答
2

在 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()数组的功能。您可以filter()在比较数据后使用或返回map()

于 2018-02-05T19:58:19.907 回答
0

For react-table 7 you can listen for input changes outside and call setFilter:

useEffect(() => {
  // This will now use our custom filter for age
  setFilter("age", ageOutside);
}, [ageOutside]);

See https://codesandbox.io/s/react-table-filter-outside-table-bor4f?file=/src/App.js

于 2021-08-05T01:14:06.317 回答