كيفية بناء Datagrid في الوقت الحقيقي قابل للتحرير في React

تتيح لك شبكة البيانات عرض البيانات وتحريرها. هذه ميزة حيوية في معظم التطبيقات التي تعتمد على البيانات.

ربما تكون قد نفذت هذا في أحد تطبيقات React الخاصة بك في الماضي. ربما استخدمت مكتبات مثل رد فعل تمهيد جدول أو رد فعل شبكة أو رد فعل الجدول. مع هؤلاء ، يمكنك إضافة Datagrid إلى تطبيق React الخاص بك. ولكن ماذا لو أردت إجراء التغييرات في الوقت الفعلي ومزامنة التحديثات عبر جميع الأجهزة المتصلة ومتصفحاتها؟

في هذه المقالة ، سأوضح لك كيفية إنشاء شبكة بيانات في الوقت الفعلي في React باستخدام جدول التفاعلات و Hamoni Sync.

جدول رد الفعل عبارة عن مكتبة سريعة وخفيفة الوزن لعرض الجداول في React ، وهي تدعم ترقيم الصفحات والعديد من الميزات الأخرى.

Hamoni Sync هي خدمة مزامنة لحالة الوقت الحقيقي والتي تمكنك من مزامنة حالة التطبيق في الوقت الحقيقي. سأوضح لك كيفية إنشاء شبكة بيانات بأسماء الأشخاص الأولى والأخيرة.

إذا كنت ترغب في المتابعة ، يجب أن يكون لديك بعض المعرفة بـ React وأن يكون لديك الأدوات التالية مثبتة:

  1. NodeJS
  2. npm & npx. إذا قمت بتثبيت الإصدار 5.2.0 أو إصدار أحدث من npm ، فسيتم تثبيت npx إلى جانب npm.
  3. إنشاء-رد-التطبيق

أنشئ تطبيق React

أولاً سننشئ مشروع React جديدًا باستخدام تطبيق create-react-app.

افتح سطر الأوامر وقم بالتشغيل npx create-react-app realtime-react-datatable. سيؤدي هذا إلى تمهيد تطبيق React لنا عن طريق إنشاء دليل جديد realtime-react-datatableبالملفات المطلوبة لبناء تطبيق React.

مع إنشاء تطبيق React ، نحتاج إلى تثبيت جدول رد الفعل و Hamoni Sync. لا يزال في سطر الأوامر ، قم بتشغيل cd realtime-react-datatableللتبديل إلى دليل التطبيق. قم بالتشغيل npm i react-table hamoni-syncفي سطر الأوامر لتثبيت كلتا الحزمتين.

تقديم Datagrid

لتقديم مجموعة البيانات ، سنستخدم مكون جدول التفاعل. افتح الملف src/App.jsوقم بتحديثه بالرمز أدناه:

import React, { Component } from "react";import logo from "./logo.svg";import "./App.css";// Import React Tableimport ReactTable from "react-table";import "react-table/react-table.css";// Import Hamoni Syncimport Hamoni from "hamoni-sync";
class App extends Component { constructor() { super(); this.state = { data: [], firstName: "", lastName: "" }; }
 handleChange = event => { if (event.target.name === "firstName") this.setState({ firstName: event.target.value }); if (event.target.name === "lastName") this.setState({ lastName: event.target.value }); };
 handleSubmit = event => { event.preventDefault(); };
 renderEditable = cellInfo => { return ( { const data = [...this.state.data]; data[cellInfo.index][cellInfo.column.id] = e.target.innerHTML; this.setState({ data }); }} dangerouslySetInnerHTML={{ __html: this.state.data[cellInfo.index][cellInfo.column.id] }} /> ); };
 render() { const { data } = this.state;
 return ( 

Welcome to React

Add new record

FirstName: {" "} LastName:

( ) } ]} defaultPageSize={10} className="-striped -highlight" /> ); }}
export default App;

يعرض الكود أعلاه نموذجًا ومكون جدول تفاعل قابل للتحرير. /> renders a component with data, columns , and defaultPageSize props . The data props holds the data to display , and columns props for the column definition . The accessor proper ty in columns props indicates the property that holds the value to be displayed for that co lumn. Cell: this.renderEditable proper ty in columns props tells react-table that the column is editable. The other funct ions (handleSub mit & handleChange) allows getting new data entry from the form on the page.

Add Hamoni Sync

The data for the datagrid will be retrieved and updated in real-time using Hamoni Sync. We already imported the Hamoni library on line 18 in App.js;

import Hamoni from "hamoni-sync";

We need to initialize it and connect to Hamoni server. To do this we need an account and application ID. Follow these steps to create an application in Hamoni.

  1. Register and login to Hamoni dashboard
  2. Enter your preferred application name in the text field and click the create button. This should create the app and display it in the application list section.
  3. Click the button “Show AccountID” to see your account ID.

Add the following code to App.js to initialise and connect to Hamoni Sync server.

componentDidMount() { let hamoni = new Hamoni("ACCOUNT_ID", "APP_ID");
 hamoni .connect() .then(() =>; {
 }) .catch(console.log); }

The code above will connect the client device or browser to Hamoni Sync server. Copy your account and application ID from the dashboard and replace them with the string placeholder respectively.

Add the following to the function in the then() block, to be executed when it successfully connects to the server:

hamoni .get("datagrid") .then(listPrimitive => { this.listPrimitive = listPrimitive;
 this.setState({ data: [...listPrimitive.getAll()] });
 listPrimitive.onItemAdded(item => { this.setState({ data: [...this.state.data, item.value] }); });
 listPrimitive.onItemUpdated(item => { let data = [ ...this.state.data.slice(0, item.index), item.value, ...this.state.data.slice(item.index + 1) ];
 this.setState({ data: data }); });
 listPrimitive.onSync(data => { this.setState({ data: data }); }); }) .catch(console.log);

The code above calls hamoni.get("datagrid") to get the data, with datagrid as the name of the application state on Hamoni Sync. Hamoni Sync allows you to store 3 kinds of state referred to as Sync primitives. They are:

  1. Value Primitive: This kind of state holds simple information represented with datatypes like string, boolean or numbers. It is best suited for cases such as unread message count, toggles, etc.
  2. Object Primitive: Object state represents states that can be modeled as a JavaScript object. An example usage could be storing the score of a game.
  3. List Primitive: This holds a list of state objects. A state object is a JavaScript object. You can update an item based on its index in the list.

If the state is available it resolves and returns a promise with the state primitive object. This object gives us access to methods to update state and get state updates in real-time.

On line 36 we used the getAll() method to get data and set the state for the React component. Also, the methods onItemAdded() and onItemUpdated() are used to get updates when an item is added or updated. The onSync() method is useful in a scenario where a device or browser loses connection, and when it reconnects, it tries to get the latest state from the server and update the local state if there's any.

Add & Update items

From the previous section, we are able to get the data for the datagrid and update the state when an item is added or update. Let’s add code to add new items and update an item when a column has been edited. Add the following code to the handleSubmit method:

handleSubmit = event => { this.listPrimitive.push({ firstName: this.state.firstName, lastName: this.state.lastName }); this.setState({ firstName: "", lastName: "" }); event.preventDefault();};

This code gets the first and last name from the form and adds it to the list state primitive on Hamoni Sync by calling the push() method. This will trigger the onItemAdded() method.

In order to update items as they get edited in the datagrid, we will update the function passed to the onBlur props on line 84 as follows:

onBlur={e => { let row = this.state.data[cellInfo.index]; row[cellInfo.column.id] = e.target.innerHTML; this.listPrimitive.update(cellInfo.index, row);}}

This code updates the item at the index retrieved from the cellInfo object. To update a list state primitive in Hamoni Sync, you call the update()method with the index of the item and the value to update. The renderEditable method should now look like this after the last change:

renderEditable = cellInfo => { return ( { let row = this.state.data[cellInfo.index]; row[cellInfo.column.id] = e.target.innerHTML; this.listPrimitive.update(cellInfo.index, row); }} dangerouslySetInnerHTML={{ __html: this.state.data[cellInfo.index][cellInfo.column.id] }} /> ); };

At this point we have almost all that’s needed to run the app except the initial data that will be rendered on the datagrid.

We need to create the state and give it some data on Hamoni Sync. Add a new file seed.js at the root of your working directory and add to it the following code:

const Hamoni = require("hamoni-sync");
let hamoni = new Hamoni("AccountID", "APP_ID");
hamoni .connect() .then(response => { hamoni .createList("datagrid", [ { firstName: "James", lastName: "Darwin" }, { firstName: "Jimmy", lastName: "August" } ]) .then(() => console.log("create success")) .catch(console.log); }) .catch(console.log);

This will create a list primitive state on Hamoni Sync, with a name of datagrid. Replace the AccountID and APP_ID string with your account and application ID. Open the command line and run node seed.js. This should succeed and print out create success message.

Now we can start the React app and see our app in action! Run the command npm start in the command line and it'll open the application in your default browser.

Hooray! We have a real-time editable datagrid with pagination!

Conclusion

We have built a real-time datagrid in React using react-table and Hamoni Sync. With react-table powering the datagrid and Hamoni Sync handling the state for the datagrid. This was all achieved in few lines of code and less effort designing real-time state logic. You can get the finished app of what we built on GitHub. It’s possible to track which cell is being edited or lock the cells currently being edited by another user. I’ll leave that as a weekend hack for you.

Feel free to leave a comment if anything is not clear or encounter problems while trying to add lock or highlight cells being edited.

Happy coding ?