MaterialTable — между отправками была обнаружена мутация состояния

У меня есть два набора данных, которые я хочу отображать в табличных данных, поэтому в зависимости от требований я пытаюсь установить состояние табличных данных с разными данными.

Компонент таблицы:

<Grid item xs={12} md={8}>
  {this.state.showTable && this.state.tableData !== null && (
       <MaterialTable
         title="Manage Blogs"
         columns={this.state.columns}
         data={this.state.tableData}
         actions={[
         {
           icon: "open_in_new",
           tooltip: "Open Blog",
           onClick: (blog, rowData) => {
            // Do save operation
            this.props.history.push("partner/blog/" + rowData._id);
             }
            }
          ]}
        />
  )}
</Grid>

Ниже приведены два места, где я меняю состояние tableData:

  changeSelectedComponent = label => {
    debugger;
    if (this.state.selectedComponent.toString() !== label)
      this.setState(state => ({ selectedComponent: label }));
    if (label === "Blogs") {
      if (
        this.props.partnerBlogs === null &&
        this.props.apiCallsInProgress === 0
      ) {
        this.props.actions
          .loadPartnerBlogs(this.props.auth0UserProfile.sub)
          .catch(error => {
            alert("Loading events failed" + error);
          });
      } else if (this.props.apiCallsInProgress === 0) {
        this.setState({ tableData: this.props.partnerBlogs, showTable: true });
      }
    } else if (label === "Your Events") {
      if (
        this.props.partnerEvents === null &&
        this.props.apiCallsInProgress === 0
      ) {
        this.props.actions
          .loadPartnerEvents(this.props.auth0UserProfile.sub)
          .catch(error => {
            alert("Loading events failed" + error);
          });
      } else if (this.props.apiCallsInProgress === 0) {
        this.setState({ tableData: this.props.partnerEvents, showTable: true });
      }
    }
  };

Другое место после получения нового реквизита:

  componentWillReceiveProps(nextProps) {
    debugger;
    if (
      this.props.partnerBlogs !== nextProps.partnerBlogs &&
      nextProps.apiCallsInProgress === 0
    ) {
      this.setState({
        tableData: nextProps.partnerBlogs,
        showTable: true
      });
    }
    if (
      this.props.partnerEvents !== nextProps.partnerEvents &&
      nextProps.apiCallsInProgress === 0
    ) {
      this.setState({
        tableData: nextProps.partnerEvents,
        showTable: true
      });
    }
  }

Начальное состояние tableData равно null. Нет проблем, когда я устанавливаю состояние в первый раз, но при изменении состояния получаю следующую ошибку

Обнаружена мутация состояния между рассылками в пути partnerEvents.0.tableData. Это может привести к некорректному поведению. (http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments)

Не знаю, что не так в моем коде, спасибо за помощь


person mohit uprim    schedule 28.05.2019    source источник
comment
Можете ли вы поделиться своим редукс-кодом? Предупреждение, похоже, подразумевает ошибку в редукторе. Можете ли вы предоставить минимальный, полный и поддающийся проверке пример, воспроизводящий проблему?   -  person Drew Reese    schedule 28.05.2019
comment
Эта конкретная ошибка звучит так, как будто она действительно происходит вне редукторов. Мое первое предположение состоит в том, что <MaterialTable>, возможно, каким-то образом мутирует свои данные?   -  person markerikson    schedule 28.05.2019
comment
Да, я пробовал так много подходов, а также с одним состоянием для таблицы, но, похоже, оно не работает, когда я пытаюсь изменить данные таблицы через состояние.   -  person mohit uprim    schedule 28.05.2019
comment
@markerikson у вас есть предложения, что я могу попробовать, спасибо   -  person mohit uprim    schedule 28.05.2019
comment
Стоит отметить, что это открытая проблема с таблицей материалов. Есть запрос функции, чтобы иметь опцию без мутации. См.: ссылка   -  person Jeffrey    schedule 10.02.2020


Ответы (1)


materialTable изменил ваши данные, добавив объект TableData, который содержит элементы строки «Id» и «checked», поэтому я рекомендую использовать это в своем коде, если вы хотите избежать мутации:

data={this.state.yourData.map(x =>Object.assign({}, x))}

Пожалуйста, дайте мне знать, если это позволит избежать проблем с мутацией, с которыми вы столкнулись.

С уважением

person Orestes    schedule 30.05.2019
comment
Это предотвращает возникновение проблемы мутации, но имеет побочные эффекты. Я включаю выбор строк, и когда я использую такой код, это приводит к тому, что проверенные строки не отслеживаются должным образом. Если я выберу одну строку, все в порядке. Если я выберу вторую строку, первая выбранная строка будет снята. Фактически я могу выбрать только одну строку. - person Jeffrey; 06.02.2020
comment
Вы должны хранить ссылку на проверенные строки за пределами таблицы и обновлять это поле перед отправкой данных в таблицу. Например, проверьте этот код: ///////////////////////////////////// response.data.forEach((row , i) => { const idsSelected = this.state.myListChecked.map(u => u.Id);if (idsSelected.includes(row.Id)) { row.tableData = {checked: true }; } }) ; ////////////////////////////////////////////////// ///// - person Orestes; 07.02.2020
comment
Спасибо @Орест. Итак, я создаю новый массив данных с помощью setState и передаю этот массив данных в таблицу. Затем в useEffect я копирую данные, которые хочу использовать для создания таблицы, используя метод Object.assign. Затем выполните итерацию по этому массиву, чтобы установить значение tableData.checked на основе другого массива selectedIds и присвоить этот массив setState. Выбор таблицы работает, и я НЕ получаю ошибку мутации. - person Jeffrey; 10.02.2020