【问题标题】:Is this okay to set await on set state in react class?这可以在反应类中设置等待状态吗?
【发布时间】:2019-12-07 20:58:11
【问题描述】:

您好,我是新来的反应,我正在实施react-table。我知道如果任何道具发生变化,反应会自动呈现组件。现在,对于我的工作表,我正在尝试根据复选框隐藏和显示列上的过滤器。 react-table 已经提供了一个 filterable 选项来执行此操作。但我不想在我的actions 列中显示过滤器。

这里

class JobsTable extends React.Component {
  constructor() {
    super();
    this.state = {
      data: [],
      isFilterable: true,
    };
  }

  componentDidMount() {
    this.getJobs();
  }


  getFormattedDate(dateString) {
    const current_datetime = new Date(dateString);
    const formatted_date =
      ('0' + current_datetime.getDate()).slice(-2) +
      '/' +
      ('0' + (current_datetime.getMonth() + 1)).slice(-2) +
      '/' +
      current_datetime.getFullYear();
    return formatted_date;
  }

  getJobs = async pageIndex => {
    pageIndex = pageIndex || 1;
    this.setState({ isLoading: true });

    const { recordsToFetch } = this.state;
    const resp = await getAllJobs(pageIndex, recordsToFetch);

    if (resp.success) {
      this.setState({
        data: resp.data.jobs,
        pages: Math.ceil(resp.data.totalRecords / recordsToFetch),
        isLoading: false,
        showPagination: resp.data.jobs.length > 0,
      });
    } else {
      this.setState({ data: [], isLoading: false, showPagination: false });
    }
    ReactTooltip.rebuild();
  };

  getCell(row) {
    let value = row.value !== undefined && row.value !== null ? row.value : '';
    if (row.column.Header === 'Submitted') {
      value = this.getFormattedDate(value);
    }
    if (row.column.Header === 'Problem Summary') {
      value = Array.isArray(value) ? value.join('. ') : value;
    }
    if (row.column.Header === 'Quotes') {
      value = JSON.stringify(value);
    }
    if (row.column.Header === 'Actions') {
      return (
        <>
          <div
            id="view"
            className="react-table-cell-style"
            style={{ display: 'inline', cursor: 'pointer' }}>
            {' '}
            <a
              rel="noopener noreferrer"
              target="_blank"
              href={`/job/${row.original.userId}/${row.original.jobId}`}>
              View
            </a>
          </div>{' '}
          <div
            id="edit"
            className="react-table-cell-style"
            style={{ display: 'inline', cursor: 'pointer' }}>
            | Edit
          </div>{' '}
          <div
            id="viewQuote"
            style={{ display: 'inline', cursor: 'pointer' }}
            className="react-table-cell-style">
            {value > 0 && `| Quote${value > 1 ? 's' : ''}`}
          </div>
        </>
      );
    }
    return (
      <div data-tip={row.column.Header + ' : ' + value} className="react-table-cell-style">
        <span>{value}</span>
      </div>
    );
  }

  getHeader(headerName, valueAccessor, sortable = true) {
    const { isFilterable } = this.state;
    const headerClassName = 'react-table-header';
    return {
      headerClassName: headerClassName,
      Header: headerName,
      accessor: valueAccessor,
      Cell: row => this.getCell(row),
      filterable: headerName === 'Actions' ? false : isFilterable,
      sortable: sortable,
      width: headerName === 'Actions' ? 140 : undefined,
    };
  }


  render() {
    let jobColumns = [
      this.getHeader('Job ID', 'jobId'),
      this.getHeader('User ID', 'userId'),
      this.getHeader('Name', 'name'),
      this.getHeader('Email', 'email'),
      this.getHeader('Submitted', 'submitted'),
      this.getHeader('Status', 'status'),
      this.getHeader('Phone Number', 'number'),
      this.getHeader('Device', 'device'),
      this.getHeader('Make', 'make'),
      this.getHeader('Model', 'model'),
      this.getHeader('Problem Summary', 'problemSummary'),
      this.getHeader('Anything else?', 'anythingElse'),
      this.getHeader('Postcode', 'postcode'),
      this.getHeader("T's Matched", 'techspertMatchedCount'),
      this.getHeader('Not Available', 'techspertNotAvailable'),
      this.getHeader('Quotes', 'quotesCount'),
      this.getHeader('Viewed Quote', 'viewedQuote'),
      this.getHeader('Chatted with T', 'isChatted'),
      this.getHeader('Got to Payment', 'gotToPayment'),
      this.getHeader('Actions', 'quotesCount', false),
    ];

    const {
      data,
      isFilterable,
    } = this.state;


    const setFilters = async () => {
      const { isFilterable } = this.state;
      await this.setState({ isFilterable: !isFilterable });
      this.getJobs();
    };

    return (
      <div className="jobsTable-Container">
        <div className="jobsTable_show-filter">
          <input
            type="checkbox"
            onChange={setFilters}
            checked={isFilterable}
            value={isFilterable}
          />
          Show Filters
        </div>
          <ReactTable
            data={data}
            columns={jobColumns}
            filterable
          />
      </div>
    );
  }
}
export default JobsTable;

我想提出的问题是,可以在setFiltersmethood 中使用await。因为如果我不这样做并调用getJobsmethood,旧值不会更新。这样可以吗?

【问题讨论】:

  • 不,你不要在 setState 中等待
  • “没问题”,但不一定有用。
  • 这里是你如何使用await的一般情况......它会返回一个Promise吗?如果没有,那就不要打扰
  • await 运算符用于等待 Promise。它只能异步函数中使用。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 所以,它不会像你预期的那样工作,也没有理由这样做。
  • 这能回答你的问题吗? React setState and await

标签: javascript reactjs async-await react-table


【解决方案1】:

这里的主要问题是getJobs 依赖于状态是最新的,但由于状态更新是异步的,更新发生在getJobs 调用之后。通过添加await,您将getJobs 调用推迟到微任务。这可能(也可能不会!)在状态更新之后:

  ------------- time ---------->
  setState -------> state update
          await --------> getJobs

所以你的“修复”是有问题的。而是使用setState 的第二个参数,它在状态更新后被定义地调用:

 this.setState({ isFilterable: !isFilterable }, () => this.getJobs());

甚至更好,不依赖于当前状态:

 this.setState(({ isFilterable }) => ({ isFilterable: !isFilterable }), () => this.getJobs());

上面的图表变成了:

  setState -> state update -> getJobs

【讨论】:

  • 哦,谢谢。我不知道我们也可以在设置状态下写这样的 () => this.getJobs()
【解决方案2】:

您不应该将 await 与 setState 结合使用,我认为您正在寻找的是这样的。

this.setState({ 
    isFilterable: !isFilterable 
}, () => {
    this.getJobs()
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-06
    • 2014-06-27
    • 2017-11-26
    • 2020-03-15
    • 2017-03-03
    • 1970-01-01
    • 2020-05-07
    • 2021-08-07
    相关资源
    最近更新 更多