You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React单次调用无法两次更新状态及表格性别过滤切换问题

解决React Table性别过滤时的数据切换问题

嘿,我完全懂你现在的困扰!你遇到的核心问题其实是直接修改了用于展示的state数据,导致原始数据被覆盖,后续过滤找不到需要的记录。你的临时重置方案能work,但其实有更优雅的实现方式,不用每次过滤前都重置数据,咱们一步步来改:

问题根源

你之前的做法是每次点击按钮就直接修改this.state.data,比如点击“Show All Men”后,data就变成了只有男性的数组;这时再点“Show All The Ladies”,是基于已经过滤过的男性数组去过滤女性,自然找不到数据,表格就空了。

正确思路:保留原始数据,用过滤条件动态计算展示数据

我们只需要把过滤条件存在state里,而不是直接修改展示数据。渲染表格时,始终从原始的defaultData出发,根据当前的过滤条件计算出要展示的内容。这样原始数据永远不会被修改,切换过滤条件时就能正确拿到对应的数据。

修改后的完整代码

import React from "react";
import { render } from "react-dom";
import ReactTable from "react-table";
import "react-table/react-table.css";

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      // 只保留一份原始数据,不用重复存储data
      defaultData: [
        {'id':1,first_name:'Ilka',last_name:'Riddel',email:'iriddel0@blogger.com',gender:'Female'},
        {'id':2,first_name:'Myrwyn',last_name:'Skinner',email:'mskinner1@cmu.edu',gender:'Male'},
        {'id':3,first_name:'Almira',last_name:'Kubu',email:'akubu2@google.ru',gender:'Female'},
        {'id':4,first_name:'Eloisa',last_name:'Maltster',email:'emaltster3@phoca.cz',gender:'Female'},
        {'id':5,first_name:'Vite',last_name:'Capin',email:'vcapin4@noaa.gov',gender:'Male'},
        {'id':6,first_name:'Zelig',last_name:'Crippin',email:'zcrippin5@blogtalkradio.com',gender:'Male'},
        {'id':7,first_name:'Persis',last_name:'Middlemiss',email:'pmiddlemiss6@discovery.com',gender:'Female'},
        {'id':8,first_name:'Amelina',last_name:'Biddy',email:'abiddy7@noaa.gov',gender:'Female'},
        {'id':9,first_name:'Darrell',last_name:'Kemme',email:'dkemme8@clickbank.net',gender:'Male'},
        {'id':10,first_name:'Kerianne',last_name:'Formby',email:'kformby9@berkeley.edu',gender:'Female'}
      ],
      firstNameSelected: true,
      // 新增过滤条件:可选值 'all' | 'male' | 'female'
      activeFilter: 'all'
    };
  }

  handleInputChange(value) {
    this.setState({ firstNameSelected: !this.state.firstNameSelected });
  }

  handleToUpperCaseFirstName(){
    // 如果你需要实现这个功能,也应该基于defaultData处理后生成新数组,不要修改原始数据
    // 比如:
    // this.setState(prevState => ({
    //   defaultData: prevState.defaultData.map(person => ({
    //     ...person,
    //     first_name: person.first_name.toUpperCase()
    //   }))
    // }))
  }

  handleShowOnlyMale(){
    // 只修改过滤条件,不修改数据
    this.setState({ activeFilter: 'male' })
  }

  handleShowOnlyFemale(){
    this.setState({ activeFilter: 'female' })
  }

  handleShowAll(){
    // 新增显示全部的按钮逻辑
    this.setState({ activeFilter: 'all' })
  }

  render() {
    const { defaultData, firstNameSelected, activeFilter } = this.state;
    
    // 根据当前过滤条件计算要展示的数据
    const filteredData = defaultData.filter(person => {
      if (activeFilter === 'male') {
        return person.gender === 'Male';
      } else if (activeFilter === 'female') {
        return person.gender === 'Female';
      }
      // 默认显示全部
      return true;
    });

    return (
      <div>
        <div>
          <button onClick={this.handleToUpperCaseFirstName.bind(this)}>
            HIGHLIGHT FIRSTNAME (UPPERCASE)
          </button>
          <button onClick={this.handleShowOnlyMale.bind(this)}>Show All Men</button>
          <button onClick={this.handleShowOnlyFemale.bind(this)}>Show All The Ladies</button>
          <button onClick={this.handleShowAll.bind(this)}>Show All</button>
        </div>
        <ReactTable
          data={filteredData} // 用计算后的过滤数据
          columns={[
            {
              columns: [
                {
                  Header: "First Name",
                  accessor: "first_name",
                  show: firstNameSelected
                },
                {
                  Header: "Last Name",
                  id: "last_name",
                  accessor: d => d.last_name
                }
              ]
            },
            {
              columns: [
                {
                  Header: "Email",
                  accessor: "email"
                },
                {
                  Header: "Gender",
                  accessor: "gender"
                }
              ]
            },
          ]}
          defaultPageSize={10}
          className="-striped -highlight"
        />
        <br />
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

关键修改点说明

  • 移除重复的data state:只保留一份原始的defaultData,避免数据冗余和意外覆盖。
  • 新增activeFilter state:用这个变量来记录当前的过滤状态,而不是直接修改数据。
  • 动态计算展示数据:在render方法里根据activeFilter从defaultData过滤出要展示的内容,确保每次过滤都是基于原始数据。
  • 简化按钮事件逻辑:按钮点击只需要修改activeFilter的值,不用再处理数据重置和过滤的复杂逻辑。

这样修改后,你就能轻松实现男女记录的切换,再也不会出现表格为空的问题,逻辑也更清晰易维护~

内容的提问来源于stack exchange,提问作者TwoThumbSticks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:19:57