Mobx与材质网格反应

时间:2020-03-07 22:54:05

标签: reactjs observable react-hooks mobx material-table

我认为这是一个简单的问题。我正在尝试在react中创建一个材质ui网格并能够向其添加行。我尝试了几种模式的变体,但没有任何工作适合我。我将粘贴以下示例,您可以找到代码here

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 :(得分:0)

好的,我查看了其他带有material-table标签的帖子,并找到了解决问题的关键。与其将元素推送到我的数据数组中,不如将其设置为带有新元素的全新数组。

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

事实证明,上面的示例即使进行了更改也不起作用,但是更改数组修饰符以返回新数组是解决方案的关键。

答案 1 :(得分:0)

您对修改商店的约定是正确的-通常,最好在合并新数据时创建一个新的数组或对象并将旧数据散布到新数据中。

我认为,在您的情况下,您的onClick处理程序中只有一个错字。您没有在Button元素中调用它-您正在运行箭头功能,但在内部没有调用addRow方法!我已经为您重写了它,并且还切换到了useLocalStore钩子,因为这是最近推荐使用的钩子。

这也是一个很好的机会,可以检查从React中的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;