Hogyan készítsünk egy reagáló Fix-Data-Table-t React Horgokkal

Az egyik projektem a Fixed-Data-Table-2 (FDT2) nevű könyvtárat használja, és kiválóan alkalmas rengeteg adatsor hatékony megjelenítésére.

Dokumentációjuk egy érzékeny táblázatot mutat be, amely átméretezik a böngésző szélessége és magassága alapján.

Úgy gondoltam, hogy jó lenne megosztani ezt a példát a React Hooks segítségével.

Mik azok a React Hook-ok?

Ezek olyan funkciók, amelyek olyan React funkciókat nyújtanak Önnek, mint az állapot- és életciklus-horgok ES6 osztályok nélkül.

Néhány előnye van

  • az állapotszerű logika izolálása, megkönnyítve a tesztelést
  • az állapotszerű logika megosztása renderelési kellékek vagy magasabb rendű összetevők nélkül
  • az alkalmazás aggályait logika alapján kell elkülöníteni, nem pedig az életciklusos horgoktól
  • kerülve az ES6 osztályokat, mert furcsaak, valójában nem osztályok , és még a tapasztalt JavaScript fejlesztőket is bejárják

További részletekért lásd a React hivatalos Hooks bevezetőjét.

FIGYELEM: Ne használja a gyártásban!

Az írás idején Hooks alfa. API-juk bármikor megváltoztatható.

Javaslom, kísérletezzen, szórakozzon és használja a Horgokat a mellékprojektjeiben, de csak a gyártási kódban, amíg stabilak.

A cél

Készítünk egy érzékeny Fix-Data-táblát. Nem lesz túl keskeny vagy túl széles az oldalunk számára, pontosan illeszkedik!

Beállít

Itt vannak a GitHub és a CodeSandbox linkek.

git clone //github.com/yazeedb/Responsive-FDT2-Hooks/ cd Responsive-FDT2-Hooks npm install 

A masterfióknak elkészült a projektje, ezért startha folytatni szeretné, fizesse meg a fiókot.

git checkout start

És futtassa a projektet.

npm start

Az alkalmazásnak futnia kell localhost:3000. Kezdjük a kódolást.

Táblázatstílusok importálása

Először be akarja importálni az FDT2 stíluslapját index.js, hogy az asztal ne tűnjön szétroncsoltnak.

Hamis adatok generálása

A táblázatunknak adatokra van szüksége, igaz? Hozzon létre egy fájlt a srcnevű mappában getData.js.

Adataink előállításához a félelmetes faker.js könyvtárat fogjuk használni. Ez már jött a tiéddel npm install.

Itt van a forrás, ha másolni / beilleszteni szeretné.

import faker from 'faker'; const createFakeRowData = () => ({ firstName: faker.name.firstName(), lastName: faker.name.lastName(), email: faker.internet.email(), city: faker.address.city(), salary: faker.random .number({ min: 50000, max: 500000 }) .toLocaleString('en-US', { style: 'currency', currency: 'USD' }) }); export default () => Array.from({ length: 2000 }, createFakeRowData); 

createFakeRowData objektumot ad vissza teljes névvel, e-mail-címmel, várossal és fizetéssel dollárban.

Exportált függvényünk 2000-et ad vissza.

A válasz nélküli táblázat

Megvannak az adataink, kódoljuk be most a táblázatot.

Az oldal tetején index.jsimportálja adatainkat és az FDT2 összetevőket.

import { Table, Column, Cell } from 'fixed-data-table-2'; import getData from './getData'; 

És használja őket így.

function App() { const data = getData(); return ( 
    
      { return {data[rowIndex][columnKey]}; }} />
     
       { return {data[rowIndex][columnKey]}; }} />
      
        { return {data[rowIndex][columnKey]}; }} />
       
         { return {data[rowIndex][columnKey]}; }} />
        
          { return {data[rowIndex][columnKey]}; }} />
        
       
      
     
    
    
); }

Konfiguráljuk a táblázatot az adatainkkal, és létrehozunk egy Columnminden egyes megjelenítendő mezőt.

getData az objektumok tartalmazzák az utó- / vezetéknevet, az e-mail címet, a várost és a fizetést, ezért mindegyikre szükségünk van egy oszlopra.

A felhasználói felületünk most így néz ki.

Próbálja átméretezni a böngészőablakot, és észreveszi, hogy egyáltalán nem reagál. Vagy túl nagy vagy túl kicsi a nézetablakához, és felesleges helyet hagyhat.

Menekülés a tisztátalanok elé

Mint megtudtuk, a React deklaratív jellege lehetővé teszi, hogy tiszta, determinisztikus és könnyen tesztelhető függvények segítségével írja be felhasználói felületét.

Ugyanazon bemenetnek mindig ugyanazt a kimenetet kell visszaadnia.

Néha azonban meg kell látogatnunk a „tisztátalan” világot, a DOM-manipulációhoz, olyan események hozzáadásával, mint hallgatók, előfizetések és időzítők.

HOCS és renderelési kellékek

A renderelési kellékek és a magasabb rendű alkatrészek (HOCS) a standard megoldás, de vannak olyan kompromisszumok, amelyeket a Hooks most megpróbál megoldani.

Horgok használata

A horgok az új menekülő nyílás, amely kötelező parancsot használ. Esetünkben az ablak méretének megadása az a hatás, amelyet követünk.

Hozzon létre egy új fájlt useWindowSize.js.

Két dologra lesz szükségünk ennek eléréséhez:

  1. Listen to the window’s resize event, so we’re notified of when it changes
  2. Save the width/height to share with our table

Two hooks can help:

  1. useEffect
  2. useState

useEffect

This will likely replace your componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle hooks once it’s stabilized.

useEffect's perfect for most initialization logic and reading the DOM.

It’s where we’ll set up our window resize event listeners.

For more detail, see the official docs.

useState

Super simple, this Hook returns a stateful value and a function to update it. Once we capture the window’s width/height, we’ll have useState track it.

Writing our custom Hook

According to the official docs:

A custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks.

Our custom hook will be called useWindowSize, and it’ll call the useState and useEffect hooks.

This Hook’s mainly from Gabe Ragland’s useWindowSize on useHooks.com.

// `useWindowSize.js` import { useState, useEffect } from 'react'; export default () => { const getSize = () => { return { width: window.innerWidth, height: window.innerHeight }; }; const [windowSize, setWindowSize] = useState(getSize); useEffect(() => { const handleResize = () => { setWindowSize(getSize()); }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); return windowSize; }; 

Let’s break this down.

Getting the window size

const getSize = () => { return { width: window.innerWidth, height: window.innerHeight }; }; 

getSize simply returns the window’s innerWidth and innerHeight.

Initializing useState

const [windowSize, setWindowSize] = useState(getSize); 

useState can take an initial value or a function that returns a value.

In this case we want the window’s dimensions to start, so getSize is the perfect initializer.

useState then returns an array, the first index is the value and the second index is the updater function.

Configuring useEffect

useEffect(() => { const handleResize = () => { setWindowSize(getSize()); }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); 

useEffect takes a function that will run your desired effect.

Whenever the window size changes, handleResize sets the state by giving setWindowSize the latest width/height.

Cleanup Logic

Our effect function then returns a new function, which useEffect recognizes as cleanup logic.

return () => { window.removeEventListener('resize', handleResize); }; 

When we leave the page or somehow unmount our component, this cleanup function runs and removes the resize event listener. This helps prevent memory leaks.

useEffect’s Second Argument

useEffect's first argument is the function handling our logic, but we also gave it a second argument: an empty array.

useEffect(() => { ... }, []); // empty array 

Why an empty array?

useEffect's second argument is an array of values to watch over. If any of those values change useEffect runs again.

We’re just setting/removing event listeners, which only needs to happen once.

An empty array is how we communicate “just run once” to useEffect.

Empty array = no values ever change = just run once

Return windowSize

Now that our effect’s set up, just return windowSize. As the browser’s resized, windowSize will be updated.

Using our custom Hook

Time to throw our Hook at Fixed-Data-Table2!

Back in index.js, go ahead and import useWindowSize.

And use it like so.

For fun you can console.log(windowSize) and watch it update in real-time.

Cool, we get back an object of the window’s width and height!

Instead of hardcoding our table’s width and height, we can use our Hook’s exposed state.

Now your table should adjust to the window’s dimensions.

I hope you enjoyed this tutorial!