如何在setState更新器函数中使用React事件?

时间:2019-11-27 22:04:05

标签: javascript reactjs

如何在没有shift变量的情况下编写代码?

onClick = event => {
  const shift = event.target.dataset.shift;
  this.setState(() => ({ shift }), this.filter);
};

我希望event.target.dataset.shift不在shift变量中。但是无论如何,它都会失败。这是我重做的方法:

onClick = event => {
  this.setState(() => ({ shift: event.target.dataset.shift}), this.filter);
}

它不起作用。

所有代码组件App.js:

const days = ["yesterday", "today", "tomorrow"];

class App extends React.Component {
  state = {
    day: 1,
    data: [],
    filteredData: [],
    search: "",
    shift: "first"
  };

  componentDidMount() {
    this.fetchData();
  }

  fetchData = async () => {
    const response = await fetch(`/data/${days[this.state.day]}.json`);
    const data = (await response.json()).group;
    this.setState({ data, shift: Object.keys(data)[0] }, this.filter);
  };

  loadDay = day => {
    this.setState({ day }, this.fetchData);
  };

  updateSearch = e => {
    this.setState({
      search: e.target.value
    });
  };

  filter = () => {
    this.setState(({ search, data, shift }) => {
      const s = search.toLowerCase();
      return {
        filteredData: data[shift].filter(n =>
          n.firstName.toLowerCase().includes(s)
        )
      };
    });
  };

  onClick = event => {                                                
    const shift = event.target.dataset.shift;           //эта часть
    this.setState(() => ({ shift }), this.filter);
  };

  render() {
    const { search, shift, data, filteredData } = this.state;

    return (
      <div>
        <TableSearch
          value={search}
          onChange={this.updateSearch}
          onSearch={this.filter}
        />
        {days.map((day, i) => (
          <button
            key={day}
            onClick={() => this.loadDay(i)}
            className={i === this.state.day ? "active" : ""}
          >
            {day}
          </button>
        ))}
        <br />
        {Object.keys(data).map(n => (
          <button
            data-shift={n}
            onClick={this.onClick}
            className={n === shift ? "active" : ""}
          >
            {n} shift
          </button>
        ))}
        <TableData data={filteredData} />
      </div>
    );
  }
}
export default App;

1 个答案:

答案 0 :(得分:0)

SyntheticEvent为空

由于event poolingSyntheticEvent对象在setState的{​​{1}}函数中被异步调用时已被无效。

如果您不使用先前的状态值来更新状态,则可以pass an object literal to setState。对象文字是同步构造的。

updater

它与您设置的变量类似。

优化技巧:避免事件处理

您可以做的另一种优化是避免连续this.setState({ shift: event.target.dataset.shift }, this.filter) 调用,这将使组件每次都重新渲染。

在更新过滤后的数据的同时,完全删除setState并更新onClick

shift

然后,在渲染功能中,将注意力集中在数据上,并尽可能避免使用事件对象。

  componentDidMount() {
    this.fetchData(this.state.day);
  }

  loadDay = day => {
    this.setState({ day });
    // We already know the day, there's no need to wait for the state update.
    this.fetchData(day);
  }

  fetchData = async (day) => {
    const response = await fetch(`/data/${days[day]}.json`);
    const data = (await response.json()).group;

    // We know the data and shift value, no setState needed here
    this.filter(data, Object.keys(data)[0]);
  }

  filter = (data, shift) => {
    this.setState(({ search }) => {
      const s = search.toLowerCase();
      return {
        data, // save data here instead
        shift, // and shift as well.
        filteredData: data[shift].filter(
          ({ firstName }) => firstName.toLowerCase().includes(s)
        )
      };
    });
  };