【问题标题】:Mobx React with Material GridMobx React 与 Material Grid
【发布时间】:2020-03-07 22:54:05
【问题描述】:

我认为这是一个足够简单的问题。我正在尝试在反应中创建一个材质 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 商店使用原生值(字符串和数字)但不使用对象数组。我希望我只是漏掉了一些细微的差别。

【问题讨论】:

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


    【解决方案1】:

    您对修改存储的约定是正确的 - 通常,最好创建一个新数组或对象并将旧数据传播到新数据中,同时合并新数据。

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

    这也是回顾在 React 中从onClick 属性调用函数的语法的好机会。

    onClick={handleClick} // 传递一个函数的引用,当元素被点击时React会自动调用这个函数。您无需手动调用它。换句话说,在这里放括号是错误的。

    onClick={() =&gt; handleClick} // 创建一个内联箭头函数,React 会像上面一样自动运行这个函数。它将像普通函数一样执行每一行。它将到达标识符handleClick 并且什么也不做,因为在您创建的新箭头函数中没有调用handleClick。

    onClick={() =&gt; 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;
    

    【讨论】:

    • @Scott 另外,如果您不想使用 this,则不必使用 - 这只是个人喜好。
    • 我给了你充分的信任。我对现代钩子概念是全新的,您的回答有助于我理解我一直在阅读的一些内容。
    • 像魅力一样工作!我用你的代码更新了我的例子。
    【解决方案2】:

    好的,我查看了其他带有材料表标签的帖子,并找到了我的问题的关键。我没有将元素推送到我的数据数组,而是将数组设置为一个全新的数组,并附加了新元素。

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

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

    【讨论】:

      猜你喜欢
      • 2022-10-20
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 1970-01-01
      • 2019-08-15
      • 2021-05-03
      • 2020-05-18
      • 1970-01-01
      相关资源
      最近更新 更多