Реакция Mobx с сеткой материалов - PullRequest
0 голосов
/ 08 марта 2020

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

import React from "react";
import "./styles.css";

import { observer, useObservable } from "mobx-react-lite";
import MaterialTable from "material-table";
import Button from "@material-ui/core/Button";

const columns = [
  { title: "First Name", field: "name" },
  { title: "Last Name", field: "surname" },
  { title: "Year of Birth", field: "birthYear", type: "numeric" },
  {
    title: "City of Birth",
    field: "birthCity",
    lookup: {
      34: "Haughton",
      63: "San Diego",
      88: "Henryetta"
    }
  }
];

const initialData = [
  { name: "Dak", surname: "Prescott", birthYear: 1993, birthCity: 34 }
];

const addData = [
  { name: "Troy", surname: "Aikman", birthYear: 1966, birthCity: 88 },
  { name: "Tony", surname: "Romo", birthYear: 1980, birthCity: 63 }
];
const App = observer(() => {
  const store = useObservable({
    data: initialData,
    index: 0,

    addRow() {
      if (store.index < store.data.length) {
        store.data.push(addData[store.index++]);
      }
    }
  });

  return (
    <div className="App">
      <MaterialTable
        columns={columns}
        data={store.data}
        title="Sample Material Table"
      />

      <Button onClick={() => store.addRow}>Add Row</Button>
    </div>
  );
});

export default App;

Это только одна попытка. Мои настоящие хранилища Mobx я создаю в отдельных файлах, и каждый атрибут, который можно наблюдать, я аннотирую @observable, но на этом этапе я приму абсолютно все, что работает. Я получил магазины Mobx, работающие с собственными значениями (строки и числа), но не с массивом объектов. Надеюсь, я просто упускаю небольшой нюанс.

Ответы [ 2 ]

0 голосов
/ 08 марта 2020

Вы правы в отношении соглашения об изменении хранилищ - как правило, лучше создать новый массив или объект и распространить ваши старые данные в новые, пока вы объединяете свои новые данные.

Я думаю в вашем случае у вас есть опечатка в вашем onClick обработчике. Вы не вызываете его в элементе Button - вы запускаете функцию стрелки, но внутри вы не вызываете метод addRow! Я переписал его для вас и также переключился на хук useLocalStore, так как это рекомендуется использовать в наши дни.

Это также хорошая возможность просмотреть синтаксис для вызова функций из атрибутов onClick в реакции.

onClick={handleClick} // Передав ссылку на функцию, React автоматически вызовет эту функцию при нажатии на элемент. Вам не нужно вызывать это вручную. Другими словами, ставить круглые скобки здесь неправильно.

onClick={() => handleClick} // Создав функцию встроенной стрелки, React автоматически запустит эту функцию, как описано выше. Он будет выполнять каждую строку как обычная функция. Он достигнет идентификатора handleClick и больше ничего не будет делать, потому что handleClick не вызывается в новой созданной вами функции стрелки.

onClick={() => handleClick()} // То же, что и выше, в том случае, если вы создаете встроенное функция стрелки React запустит эту функцию стрелки, как указано выше. Он будет выполнять каждую строку, а затем вызывать вашу функцию, потому что вы вызывали ее с круглыми скобками.

Надеюсь, это поможет!

Кстати, вы захотите убедиться, что источник данных у вас Вы получаете новые строки, способные принять индекс, который вы передаете. Прямо сейчас, если вы нажмете кнопку более двух раз, вы получите ошибку индекса вне границ. Но я предполагаю, что вы уже позаботились об этой части, поэтому я не изменил эту часть вашего кода.

import React from "react";
import "./styles.css";

import { useObserver } from "mobx-react-lite";
import MaterialTable from "material-table";
import Button from "@material-ui/core/Button";
import { useLocalStore } from "mobx-react";

const columns = [
  { title: "First Name", field: "name" },
  { title: "Last Name", field: "surname" },
  { title: "Year of Birth", field: "birthYear", type: "numeric" },
  {
    title: "City of Birth",
    field: "birthCity",
    lookup: {
      34: "Haughton",
      63: "San Diego",
      88: "Henryetta"
    }
  }
];

const initialData = [
  { name: "Dak", surname: "Prescott", birthYear: 1993, birthCity: 34 }
];

const addData = [
  { name: "Troy", surname: "Aikman", birthYear: 1966, birthCity: 88 },
  { name: "Tony", surname: "Romo", birthYear: 1980, birthCity: 63 }
];
const App = () => {
  const store = useLocalStore(() => ({
    data: initialData,
    index: 0,
    addRow() {
      if (this.index < this.data.length) {
        this.data = [...this.data, addData[this.index++]];
      }
    }
  }));

  return useObserver(() => (
    <div className="App">
      <MaterialTable
        columns={columns}
        data={store.data}
        title="Sample Material Table"
      />

      <Button onClick={store.addRow}>Add Row</Button>
    </div>
  ));
};

export default App;
0 голосов
/ 08 марта 2020

Хорошо, я посмотрел другие посты с тегом material-table и нашел ключ к моей проблеме. Вместо того, чтобы помещать элемент в мой массив данных, я устанавливаю массив в совершенно новый массив с добавленным новым элементом.

store.data = [...store.data, addData[store.index++]];

Как оказалось, мой пример выше не работает даже с этим изменением, но изменение модификатора массива для возврата нового массива является ключом к решению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...