【问题标题】:Get filtred data, react-bootstrap-table2获取过滤后的数据,react-bootstrap-table2
【发布时间】:2019-12-23 22:14:52
【问题描述】:

是否有任何返回过滤行的全局表选项?忽略分页。所有行匹配一个或多个textFilter?

我需要在标题中显示过滤数据的平均值的值。

我在 https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html 上找不到任何东西

onDataSizeChange,但它只提供dataSize(行数),也只在不使用分页时可用。

更新到 cmets 中的第二个问题:

class App extends Component<IProps, IState> {
  constructor(props: IProps) {
    super(props);

    this.state = {
      data: [...]
      filtredData: null
    };
  };

  const factory = patchFilterFactory(filterFactory, (filteredData) => {
     this.setState({filteredData}); // causes maximum update exceeded..
  });

  render() {
    return (
      <div>
         <BootstrapTable
          keyField='id'
          striped
          hover
          bootstrap4
          data={anbuds}
          filter={factory()}
          columns={columns}/>
      </div>
    );
  }
}

【问题讨论】:

    标签: reactjs react-bootstrap-table


    【解决方案1】:

    我的 2¢:经过一些调查(并有意避免实施 @federkun 建议的过滤器工厂包装器),我发现我可以访问呈现表的当前过滤器上下文。

    为了访问表属性,我必须添加React Ref

    class MyDataTable extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          data: props.data
        };
        this.node = React.createRef();
      }
    
      ...
    
      render() {
        return (
          <Card>
            <CardBody>
              <BootstrapTable
                ref={n => this.node = n}
                keyField="id"
                data={this.state.data}
                ...
              />
              <Button name="click-me" onClick={() => this.handleClick()}>Click me!</Button>
            </CardBody>
          </Card>
        )
      }
    }
    

    现在,当可以使用 this.node 从代码中引用 &lt;BootstrapTable&gt; 时,我可以访问所有过滤后的数据(无需分页):

      // member of MyDataTable component
      handleClick() {
        console.log(this.node.filterContext.data);
      }
    

    请注意,如果您以这种方式访问​​数据,条目将不会像您在表格中看到的那样排序,所以如果您想真正疯狂,您可以对数据进行过滤排序这样:

      // member of MyDataTable component
      handleClick() {
        const table = this.node;
        const currentDataView =
          (table.paginationContext && table.paginationContext.props.data)
          || (table.sortContext && table.sortContext.props.data) // <- .props.data (!)
          || (table.filterContext && table.filterContext.data) // <- .data (!)
          || this.state.data; // <- fallback
    
        console.log(currentDataView);
      }
    

    ...但是这变得非常疯狂。这里重要的是从paginationContext 开始——在它已经被分割成页面之前的任何东西。您可以在此处查看上下文是如何组合在一起的:react-bootstrap-table2/src/contexts/index.js

    不过,这种方法hacky - 完全避免公共 API、拦截上下文管道、读取每一层的输入。在较新的版本中情况可能会发生变化,或者这种方法可能存在我尚未发现的问题 - 请注意这一点。

    【讨论】:

      【解决方案2】:

      有点。

      您可以做到这一点的一种方法是提供过滤器道具的不同实现,并在那里获取您需要的数据。

      import BootstrapTable from "react-bootstrap-table-next";
      import filterFactory, { textFilter } from "react-bootstrap-table2-filter";
      
      function patchFilterFactory(filterFactory, onFilteredData) {
        return (...args) => {
          const { createContext, options } = filterFactory(...args)
          return {
            createContext: (...args) => {
              const { Provider: BaseProvider, Consumer } = createContext(...args)
              const Provider = class FilterProvider extends BaseProvider {
                componentDidUpdate() {
                  onFilteredData(this.data)
                }
              }
              return { Provider, Consumer } 
            },
            options
          }
        }
      }
      

      patchFilterFactory 将位于原始过滤器提供程序和您的代码之间,允许您获取所需的数据。

      使用方法:

      function Table() {
        const columns = [
          {
            dataField: "id",
            text: "Product ID"
          },
          {
            dataField: "name",
            text: "Product Name",
            filter: textFilter({
              delay: 0
            })
          },
          {
            dataField: "price",
            text: "Product Price",
            filter: textFilter({
              delay: 0
            })
          }
        ];
      
        const factory = patchFilterFactory(filterFactory, (filteredData) => {
          console.log('on filter data', filteredData)
        })
      
        return (
            <BootstrapTable
              keyField="id"
              data={props.products}
              columns={columns}
              filter={factory()}
            />
        );
      }
      

      我同意,这远非理想,但据我所知,这可能是目前唯一的方法。

      如果你想改变同一个组件的状态,我建议:

        const [filteredData, setFilteredData] = React.useState([])
      
        const factory = patchFilterFactory(filterFactory, data => {
          setFilteredData(prevData => {
            if (JSON.stringify(prevData) !== JSON.stringify(data)) {
              return data
            }
      
            return prevData
          })
        })
      

      【讨论】:

      • 如果我在工厂方法中使用 this.setState,它会崩溃导致超出最大更新。有什么办法可以避免这种情况?
      • 是的。你有我可以重现的例子吗?
      • 我已经更新了问题。是否足够,或者您需要一个完整的工作示例?
      • 今晚有空时会提供一个例子
      • @Joe,我提供了一个使用钩子的示例
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      • 1970-01-01
      相关资源
      最近更新 更多