บทนำสู่ SWR: React Hooks สำหรับการดึงข้อมูลระยะไกล
เผยแพร่แล้ว: 2022-03-10SWR เป็นไลบรารีน้ำหนักเบาที่สร้างโดย Vercel (เดิมคือ ZEIT) ที่อนุญาตให้ดึงข้อมูล แคช หรือดึงข้อมูลแบบเรียลไทม์โดยใช้ React Hooks สร้างขึ้นด้วย React Suspense ซึ่งช่วยให้คอมโพเนนต์ของคุณ "รอ" สำหรับบางสิ่งก่อนที่จะแสดงผล ซึ่งรวมถึงข้อมูลด้วย SWR ยังมาพร้อมกับคุณสมบัติที่ยอดเยี่ยม เช่น การดึงข้อมูลโดยขึ้นกับ เน้นที่การตรวจสอบซ้ำ การกู้คืนตำแหน่งการเลื่อน และอื่นๆ นอกจากนี้ยังเป็นเครื่องมือที่ทรงพลังมากเนื่องจากเป็นแบ็กเอนด์ไม่เชื่อเรื่องพระเจ้าและรองรับ TypeScript ได้ดี เป็นแพ็คเกจที่มีอนาคตที่สดใส
ทำไมคุณควรดูแล? คุณควรสนใจว่าคุณกำลังมองหาไลบรารี่ที่ไม่เพียงแต่ดึงข้อมูลจาก API แต่ยังทำให้สามารถทำสิ่งต่างๆ เช่น การแคชและการดึงข้อมูลแบบพึ่งพาได้ สิ่งที่จะกล่าวถึงในบทช่วยสอนนี้จะมีประโยชน์เมื่อสร้างแอปพลิเคชัน React ที่มีชิ้นส่วนเคลื่อนไหวจำนวนมาก เป็นที่คาดว่าคุณควรใช้ประโยชน์จาก Axios และ Fetch API แม้ว่าเราจะเปรียบเทียบว่าต่างจาก SWR อย่างไร เราจะไม่ลงรายละเอียดเกี่ยวกับวิธีการใช้งาน
ในคู่มือนี้ ฉันจะแนะนำให้คุณรู้จักกับ React Hooks สำหรับการดึงข้อมูลระยะไกลโดยการสร้างแอป Pokedex ที่ขอข้อมูลจาก Pokemon API เราจะเจาะลึกคุณสมบัติอื่นๆ ที่มาพร้อมกับ SWR ด้วยเช่นกัน และเน้นถึงความแตกต่างเมื่อเปรียบเทียบกับโซลูชันยอดนิยม เช่น Fetch API และไลบรารี Axios และให้เหตุผลว่าทำไมคุณจึงใช้ไลบรารีนี้ และเหตุใดคุณจึงควรจับตาดู SWR
เรามาเริ่มด้วยการตอบคำถามพื้นฐานกันก่อนว่า SWR คืออะไร?
SWR คืออะไร?
SWR เป็นอักษรย่อของ stale-while-revalidate เป็นไลบรารี React Hooks สำหรับการดึงข้อมูลระยะไกล SWR ทำงานกับสามขั้นตอนหลัก: ขั้นแรกจะส่งคืนข้อมูลจากแคช (ส่วนที่เก่า) จากนั้นส่งคำขอดึงข้อมูล (ส่วนตรวจสอบซ้ำ) และในที่สุดก็มาพร้อมกับข้อมูลล่าสุด แต่ไม่ต้องกังวล SWR จะจัดการขั้นตอนเหล่านี้ทั้งหมดให้เราเอง สิ่งเดียวที่เราต้องทำคือให้ useSWR
ขอพารามิเตอร์ที่จำเป็นเพื่อส่งคำขอ
SWR ยังมีคุณสมบัติที่ดีบางอย่างเช่น:
- แบ็กเอนด์ไม่เชื่อเรื่องพระเจ้า
- การนำทางหน้าอย่างรวดเร็ว
- การตรวจสอบความถูกต้องอีกครั้งในโฟกัส
- การสำรวจตามช่วงเวลา
- ขอขจัดความซ้ำซ้อน
- การกลายพันธุ์ในพื้นที่
- การแบ่งหน้า
- TypeScript พร้อมแล้ว
- รองรับ SSR
- โหมดใจจดใจจ่อ
- ตอบสนอง Native support
- น้ำหนักเบา
ฟังดูวิเศษ? SWR ช่วยลดความซับซ้อนของสิ่งต่าง ๆ และเพิ่มประสบการณ์ผู้ใช้แอพ React ของคุณอย่างแน่นอน และเมื่อเราเริ่มใช้งานในโครงการของเรา คุณจะเห็นว่าทำไมเบ็ดนี้ถึงสะดวก
สิ่งสำคัญคือต้องรู้ว่าชื่อของแพ็คเกจคือ swr
หรือ SWR และ hook ที่ใช้เพื่อรับคุณสมบัติ SWR มีชื่อว่า useSWR
ตามทฤษฎีแล้ว SWR อาจเป็นสิ่งที่คุณต้องการเพื่อปรับปรุงการดึงข้อมูลของคุณ อย่างไรก็ตาม เรามีสองวิธีที่ยอดเยี่ยมในการสร้างคำขอ HTTP ในแอปของเรา นั่นคือ Fetch API และไลบรารี Axios
เหตุใดจึงใช้ไลบรารีใหม่เพื่อดึงข้อมูล มาลองตอบคำถามที่ถูกต้องในหัวข้อถัดไป
เปรียบเทียบกับการดึงข้อมูลและ Axios
เรามีหลายวิธีในการสร้างคำขอ HTTP ในแอพ React ของเราแล้ว และสองวิธีที่ได้รับความนิยมมากที่สุดคือ Fetch API และไลบรารี Axios ทั้งคู่ยอดเยี่ยมและช่วยให้เราสามารถดึงหรือส่งข้อมูลได้อย่างง่ายดาย อย่างไรก็ตาม เมื่อดำเนินการเสร็จสิ้น การดำเนินการดังกล่าวจะไม่ช่วยให้เราแคชหรือแบ่งหน้าข้อมูล คุณต้องดำเนินการเอง
Axios หรือ Fetch จะจัดการคำขอและส่งคืนการตอบกลับที่คาดไว้ ไม่มีอะไรมากไปกว่านี้
และเมื่อเทียบกับ SWR จะแตกต่างออกไปเล็กน้อยเนื่องจาก SWR ภายใต้ประทุนใช้ Fetch API เพื่อขอข้อมูลจากเซิร์ฟเวอร์ ซึ่งเป็นประเภทของเลเยอร์ที่สร้างขึ้นบนนั้น อย่างไรก็ตาม มันมีคุณสมบัติที่ดีบางอย่าง เช่น การแคช การแบ่งหน้า การกู้คืนตำแหน่งการเลื่อน การดึงข้อมูลขึ้นอยู่กับ ฯลฯ และเพื่อให้แม่นยำระดับของการเกิดปฏิกิริยาที่ Axios หรือการดึงข้อมูลไม่มี เป็นข้อได้เปรียบอย่างมากเนื่องจากการมีคุณสมบัติดังกล่าวช่วยให้แอป React ของเรารวดเร็วและใช้งานง่าย และลดขนาดโค้ดของเราลงอย่างเห็นได้ชัด
และเพื่อสรุป พึงระลึกไว้เสมอว่า SWR ไม่เหมือนกับ Axios หรือการดึงข้อมูล แม้ว่าจะช่วยในการจัดการกับคำขอ HTTP ก็ตาม SWR นั้นล้ำหน้ากว่าพวกมัน มันมีการปรับปรุงบางอย่างเพื่อให้แอพของเราซิงโครไนซ์กับแบ็กเอนด์และด้วยเหตุนี้จึงเพิ่มประสิทธิภาพของแอพของเรา
ตอนนี้เรารู้แล้วว่า SWR มีความแตกต่างกันอย่างไรเมื่อเปรียบเทียบกับไลบรารี Axios หรือ Fetch API ถึงเวลาที่จะลงลึกถึงเหตุผลที่ใช้เครื่องมือดังกล่าว
การอ่านที่แนะนำ : การ ใช้ REST API ในการตอบสนองด้วยการดึงข้อมูลและ Axios
เหตุใดจึงต้องใช้ SWR สำหรับการดึงข้อมูล
ดังที่ฉันได้กล่าวไว้ก่อนหน้านี้ SWR มาพร้อมกับคุณสมบัติที่มีประโยชน์ซึ่งช่วยเพิ่มความสามารถในการใช้งานแอพของคุณได้อย่างง่ายดาย ด้วย SWR คุณสามารถแบ่งหน้าข้อมูลของคุณในเวลาไม่นานโดยใช้ useSWRPages
คุณยังสามารถดึงข้อมูลที่ขึ้นอยู่กับคำขออื่นหรือกู้คืนตำแหน่งการเลื่อนเมื่อคุณกลับไปที่หน้าที่กำหนด และอื่นๆ อีกมากมาย
โดยปกติ เราจะแสดงข้อความโหลดหรือสปินเนอร์ให้ผู้ใช้เห็นขณะดึงข้อมูลจากเซิร์ฟเวอร์ และด้วย SWR คุณสามารถทำให้ดีขึ้นได้ด้วยการแสดงข้อมูลแคชหรือข้อมูลเก่าแก่ผู้ใช้ในขณะที่ดึงข้อมูลใหม่จาก API และเมื่อดำเนินการเสร็จสิ้น ระบบจะตรวจสอบข้อมูลอีกครั้งเพื่อแสดงเวอร์ชันใหม่ และคุณไม่จำเป็นต้องดำเนินการใดๆ SWR จะแคชข้อมูลในครั้งแรกที่คุณดึงข้อมูลและดึงข้อมูลโดยอัตโนมัติเมื่อมีการส่งคำขอใหม่
จนถึงตอนนี้ เราเห็นแล้วว่าเหตุใดการใช้ SWR บน Axios หรือการดึงข้อมูลจึงดีกว่า ขึ้นอยู่กับสิ่งที่คุณตั้งเป้าที่จะสร้าง แต่ในหลายกรณี ฉันจะแนะนำให้ใช้ SWR เพราะมันมีคุณสมบัติที่ยอดเยี่ยมที่นอกเหนือไปจากการดึงและส่งคืนข้อมูล
ที่กล่าวว่าตอนนี้เราสามารถเริ่มสร้างแอป React และใช้ไลบรารี SWR เพื่อดึงข้อมูลระยะไกลได้
มาเริ่มด้วยการตั้งโครงการใหม่กัน
การตั้งค่า
ดังที่ฉันได้กล่าวไว้ก่อนหน้านี้ในบทนำ เราจะสร้างแอปที่ดึงข้อมูลจาก Pokemon API คุณสามารถใช้ API อื่นได้หากต้องการ ฉันจะใช้ตอนนี้
และในการสร้างแอพใหม่ เราต้องรันคำสั่งต่อไปนี้บนเทอร์มินัล:
npx create-react-app react-swr
ต่อไป เราต้องติดตั้งไลบรารี SWR โดยไปที่โฟลเดอร์ที่มีแอป React ก่อน
cd react-swr
และรันบนเทอร์มินัลด้วยคำสั่งต่อไปนี้เพื่อติดตั้งแพ็คเกจ SWR
yarn add swr
หรือถ้าคุณใช้ npm:
npm install swr
ตอนนี้เราตั้งค่าเสร็จแล้ว มาจัดโครงสร้างโครงการดังต่อไปนี้เพื่อเริ่มใช้ SWR:
src ├── components | └── Pokemon.js ├── App.js ├── App.test.js ├── index.js ├── serviceWorker.js ├── setupTests.js ├── package.json ├── README.md ├── yarn-error.log └── yarn.lock
อย่างที่คุณเห็น โครงสร้างโฟลเดอร์นั้นเรียบง่าย สิ่งเดียวที่ควรสังเกตคือโฟลเดอร์ components
ที่เก็บไฟล์ Pokemon.js
จะใช้ในภายหลังเป็นองค์ประกอบการนำเสนอเพื่อแสดงโปเกมอนตัวเดียวเมื่อเราได้รับข้อมูลจาก API
ยอดเยี่ยม! ด้วยวิธีนี้ เราสามารถเริ่มดึงข้อมูลจาก API โดยใช้ useSWR
กำลังดึงข้อมูลระยะไกล
แพ็คเกจ SWR มีคุณสมบัติที่มีประโยชน์บางอย่างดังที่เราได้เห็นข้างต้น อย่างไรก็ตาม มีสองวิธีในการกำหนดค่าไลบรารีนี้: ในเครื่องหรือทั่วโลก
การตั้งค่าในเครื่องหมายความว่าทุกครั้งที่เราสร้างไฟล์ใหม่ เราต้องตั้งค่า SWR อีกครั้งเพื่อให้สามารถดึงข้อมูลระยะไกลได้ และการตั้งค่าส่วนกลางช่วยให้เรานำส่วนหนึ่งของการกำหนดค่ากลับมาใช้ใหม่ภายในไฟล์ต่างๆ ได้ เนื่องจากฟังก์ชัน fetcher
สามารถประกาศเพียงครั้งเดียวและใช้ได้ทุกที่
และไม่ต้องกังวล เราจะเห็นทั้งสองอย่างในบทความนี้ แต่สำหรับตอนนี้ มาเริ่มกันเลยดีกว่าและเพิ่มโค้ดที่มีความหมายในไฟล์ App.js
การแสดงข้อมูล
import React from 'react' import useSWR from 'swr' import { Pokemon } from './components/Pokemon' const url = 'https://pokeapi.co/api/v2/pokemon' const fetcher = (...args) => fetch(...args).then((res) => res.json()) function App() { const { data: result, error } = useSWR(url, fetcher) if (error) return <h1>Something went wrong!</h1> if (!result) return <h1>Loading...</h1> return ( <main className='App'> <h1>Pokedex</h1> <div> {result.results.map((pokemon) => ( <Pokemon key={pokemon.name} pokemon={pokemon} /> ))} </div> </main> ) } export default App
อย่างที่คุณเห็น เราเริ่มต้นด้วยการนำเข้า useSWR
จากไลบรารี SWR นี่เป็นการประกาศ URL ของ API ที่คุณต้องการรับข้อมูล และฟังก์ชันในการดึงข้อมูลเหล่านี้
ฟังก์ชัน fetcher
ใช้สำหรับแปลงข้อมูลเป็น JSON รับข้อมูลที่ดึงออกมาเป็นอาร์กิวเมนต์และส่งคืนบางสิ่ง
โปรดสังเกตว่าที่นี่ ฉันใช้โอเปอเรเตอร์ Rest ( (...args)
) เนื่องจากฉันไม่แน่ใจเกี่ยวกับประเภทและความยาวของข้อมูลที่ได้รับเป็นพารามิเตอร์ ดังนั้น ฉันจึงคัดลอกทุกอย่างก่อนที่จะส่งผ่านอีกครั้งเพื่อเป็นอาร์กิวเมนต์ในการ fetch
เมธอดที่จัดเตรียมโดย useSWR
ซึ่งแปลงข้อมูลเป็น JSON และส่งคืน
ที่กล่าวว่าขณะนี้ fetcher
และ url
ของ API สามารถส่งผ่านเป็นพารามิเตอร์ไปยัง useSWR
hook ได้ ด้วยเหตุนี้ จึงสามารถร้องขอและส่งคืนสถานะสองสถานะ: ข้อมูลที่ดึงมาและสถานะข้อผิดพลาด และ data: result
เหมือนกับ data.result
เราใช้ object destructuring เพื่อดึง result
จาก data
ด้วยค่าที่ส่งคืน ตอนนี้เราสามารถตรวจสอบว่าดึงข้อมูลสำเร็จแล้วหรือยัง จากนั้นวนซ้ำ และสำหรับผู้ใช้แต่ละคน ให้ใช้องค์ประกอบโปเกมอนเพื่อแสดง
ตอนนี้เรามีข้อมูลแล้วและส่งต่อไปยังส่วนประกอบโปเกมอน ถึงเวลาอัปเดต Pokemon.js
เพื่อให้สามารถรับและแสดงข้อมูลได้
การสร้างส่วนประกอบโปเกมอน
import React from 'react' import useSWR from 'swr' const fetcher = (...args) => fetch(...args).then((res) => res.json()) export const Pokemon = ({ pokemon }) => { const { name } = pokemon const url = 'https://pokeapi.co/api/v2/pokemon/' + name const { data, error } = useSWR(url, fetcher) if (error) return <h1>Something went wrong!</h1> if (!data) return <h1>Loading...</h1> return ( <div className='Card'> <span className='Card--id'>#{data.id}</span> <img className='Card--image' src={data.sprites.front_default} alt={name} /> <h1 className='Card--name'>{name}</h1> <span className='Card--details'> {data.types.map((poke) => poke.type.name).join(', ')} </span> </div> ) }
ที่นี่ เรามีองค์ประกอบที่ได้รับข้อมูลโปเกมอนเพียงรายการเดียวจาก API และแสดงข้อมูลนั้น อย่างไรก็ตาม ข้อมูลที่ได้รับมีไม่ครบทุกช่องที่จำเป็น ดังนั้นเราจึงต้องส่งคำขออีกครั้งไปยัง API เพื่อรับวัตถุ Pokemon ที่สมบูรณ์
และอย่างที่คุณเห็น เราใช้กระบวนการเดียวกันในการดึงข้อมูล แม้ว่าครั้งนี้เราจะเพิ่มชื่อของโปเกมอนต่อท้าย URL ก็ตาม
อย่างไรก็ตาม หากคุณไม่คุ้นเคยกับการทำลายโครงสร้าง ({ pokemon })
จะเหมือนกับการรับอุปกรณ์ประกอบฉากและการเข้าถึงวัตถุโปเกมอนด้วย props.pokemon
เป็นเพียงการจดชวเลขเพื่อดึงค่าออกจากวัตถุหรืออาร์เรย์
ด้วยสิ่งนี้ หากคุณไปที่โฟลเดอร์รูทของโปรเจ็กต์และรันบนเทอร์มินัล คำสั่งต่อไปนี้:
yarn start
หรือถ้าคุณใช้ npm:
npm start
คุณควรเห็นว่ามีการดึงข้อมูลจาก Pokemon API สำเร็จและแสดงตามที่คาดไว้
ยอดเยี่ยม! ขณะนี้ เราสามารถดึงข้อมูลระยะไกลด้วย SWR ได้แล้ว อย่างไรก็ตาม การตั้งค่านี้เป็นแบบโลคัลและอาจซ้ำซ้อนเล็กน้อย เพราะคุณจะเห็นแล้วว่า App.js
และ Pokemon.js
ใช้ฟังก์ชันดึงข้อมูลเดียวกันเพื่อทำสิ่งเดียวกัน
แต่โชคดีที่แพ็คเกจนี้มาพร้อมกับผู้ให้บริการที่สะดวกชื่อ SWRConfig
ที่ช่วยกำหนดค่า SWR ทั่วโลก เป็นคอมโพเนนต์ของ wrapper ที่อนุญาตให้คอมโพเนนต์ย่อยใช้การกำหนดค่าส่วนกลางและฟังก์ชัน fetcher
ในการตั้งค่า SWR ทั่วโลก เราต้องอัปเดตไฟล์ index.js
เนื่องจากเป็นตำแหน่งที่องค์ประกอบแอปแสดงผลโดยใช้ React DOM หากต้องการ คุณสามารถใช้ SWRConfig
ได้โดยตรงในไฟล์ App.js
การกำหนดค่า SWR ทั่วโลก
import React from 'react' import ReactDOM from 'react-dom' import { SWRConfig } from 'swr' import App from './App' import './index.css' const fetcher = (...args) => fetch(...args).then((res) => res.json()) ReactDOM.render( <React.StrictMode> <SWRConfig value={{ fetcher }}> <App /> </SWRConfig> </React.StrictMode>, document.getElementById('root') )
อย่างที่คุณเห็น เราเริ่มต้นด้วยการนำเข้า SWRConfig
ซึ่งเป็นผู้ให้บริการที่ต้องการห่อส่วนประกอบที่สูงกว่าหรือเพียงส่วนหนึ่งของแอป React ของคุณที่ต้องใช้คุณสมบัติ SWR ใช้เป็นค่าอุปกรณ์ประกอบฉากที่คาดหวังวัตถุของการกำหนดค่า คุณสามารถส่งผ่านคุณสมบัติมากกว่าหนึ่งรายการไปยังวัตถุ config ที่นี่ ฉันแค่ต้องการฟังก์ชันเพื่อดึงข้อมูล
ตอนนี้ แทนที่จะประกาศฟังก์ชัน fetcher
ในทุกไฟล์ เราสร้างมันที่นี่และส่งผ่านเป็นค่าไปยัง SWRConfig
ด้วยเหตุนี้ เราจึงสามารถดึงข้อมูลได้ทุกระดับในแอปของเราโดยไม่ต้องสร้างฟังก์ชันอื่น และด้วยเหตุนี้จึงหลีกเลี่ยงความซ้ำซ้อน
นอกจากนั้น fetcher
เท่ากับ fetcher: fetcher
มันเป็นเพียงน้ำตาลประโยคที่เสนอโดย ES6 ด้วยการเปลี่ยนแปลงนั้น เราต้องอัปเดตส่วนประกอบของเราเพื่อใช้การกำหนดค่าส่วนกลาง
การใช้ Global SWR Config
import React from 'react' import useSWR from 'swr' import { Pokemon } from './components/Pokemon' const url = 'https://pokeapi.co/api/v2/pokemon' function App() { const { data: result, error } = useSWR(url) if (error) return <h1>Something went wrong!</h1> if (!result) return <h1>Loading...</h1> return ( <main className='App'> <h1>Pokedex</h1> <div> {result.results.map((pokemon) => ( <Pokemon key={pokemon.name} pokemon={pokemon} /> ))} </div> </main> ) } export default App
ตอนนี้ เราต้องส่ง url
ไป useSWR
เท่านั้น แทนที่จะส่งเมธอด url
และ fetcher
มาปรับแต่งองค์ประกอบโปเกมอนกันสักหน่อย
import React from 'react' import useSWR from 'swr' export const Pokemon = ({ pokemon }) => { const { name } = pokemon const url = 'https://pokeapi.co/api/v2/pokemon/' + name const { data, error } = useSWR(url) if (error) return <h1>Something went wrong!</h1> if (!data) return <h1>Loading...</h1> return ( <div className='Card'> <span className='Card--id'>#{data.id}</span> <img className='Card--image' src={data.sprites.front_default} alt={name} /> <h1 className='Card--name'>{name}</h1> <span className='Card--details'> {data.types.map((poke) => poke.type.name).join(', ')} </span> </div> ) }
คุณจะเห็นว่าเราไม่มีฟังก์ชัน fetcher อีกต่อไปแล้ว ด้วยการกำหนดค่าส่วนกลางซึ่งส่งผ่านฟังก์ชันไปยัง useSWR
ภายใต้ประทุน
ตอนนี้คุณสามารถใช้ฟังก์ชัน global fetcher ได้ทุกที่ในแอปของคุณ สิ่งเดียวที่ขอ useSWR
ต้องการดึงข้อมูลระยะไกลคือ URL
อย่างไรก็ตาม เรายังคงสามารถปรับปรุงการตั้งค่าเพิ่มเติมได้โดยการสร้าง hook ที่กำหนดเองเพื่อหลีกเลี่ยงการประกาศ URL ซ้ำแล้วซ้ำเล่า เพียงแต่ส่งผ่านเป็นพารามิเตอร์ของเส้นทางแทน
การตั้งค่าขั้นสูงโดยการสร้าง Hook แบบกำหนดเอง
ในการทำเช่นนั้น คุณต้องสร้างไฟล์ใหม่ในรูทของโปรเจ็กต์ชื่อ useRequest.js
(คุณสามารถตั้งชื่อไฟล์อะไรก็ได้ตามต้องการ) และเพิ่มบล็อคโค้ดด้านล่างนี้ลงไป
import useSwr from 'swr' const baseUrl = 'https://pokeapi.co/api/v2' export const useRequest = (path, name) => { if (!path) { throw new Error('Path is required') } const url = name ? baseUrl + path + '/' + name : baseUrl + path const { data, error } = useSwr(url) return { data, error } }
ในที่นี้ เรามีฟังก์ชันที่รับพาธและเลือกชื่อและผนวกเข้ากับ URL ฐานเพื่อสร้าง URL ที่สมบูรณ์ จากนั้นจะตรวจสอบว่าได้รับพารามิเตอร์ชื่อหรือไม่และจัดการตามนั้น
จากนั้น URL นั้นจะถูกส่งผ่านเป็นพารามิเตอร์ไปยังฮุ useSWR
เพื่อให้สามารถดึงข้อมูลระยะไกลและส่งคืนได้ และถ้าไม่ผ่านเส้นทางจะเกิดข้อผิดพลาด
ยอดเยี่ยม! ตอนนี้เราต้องปรับแต่งส่วนประกอบเล็กน้อยเพื่อใช้ hook ที่กำหนดเองของเรา
import React from 'react' import { useRequest } from './useRequest' import './styles.css' import { Pokemon } from './components/Pokemon' function App() { const { data: result, error } = useRequest('/pokemon') if (error) return <h1>Something went wrong!</h1> if (!result) return <h1>Loading...</h1> return ( <main className='App'> <h1>Pokedex</h1> <div> {result.results.map((pokemon) => ( <Pokemon key={pokemon.name} pokemon={pokemon} /> ))} </div> </main> ) } export default App
ตอนนี้ แทนที่จะใช้ SWR hook เราใช้ hook แบบกำหนดเองที่สร้างขึ้นบนมัน แล้วส่งผ่านเส้นทางที่เป็นอาร์กิวเมนต์ตามที่คาดไว้ ด้วยสิ่งนี้ ทุกอย่างจะทำงานเหมือนเมื่อก่อน แต่มีการกำหนดค่าที่สะอาดกว่าและยืดหยุ่นกว่ามาก
มาอัพเดทองค์ประกอบโปเกมอนกัน
import React from 'react' import { useRequest } from '../useRequest' export const Pokemon = ({ pokemon }) => { const { name } = pokemon const { data, error } = useRequest('/pokemon', name) if (error) return <h1>Something went wrong!</h1> if (!data) return <h1>Loading...</h1> return ( <div className='Card'> <span className='Card--id'>#{data.id}</span> <img className='Card--image' src={data.sprites.front_default} alt={name} /> <h1 className='Card--name'>{name}</h1> <span className='Card--details'> {data.types.map((poke) => poke.type.name).join(', ')} </span> </div> ) }
คุณสามารถดูแล้วว่า hook แบบกำหนดเองของเราทำให้สิ่งต่าง ๆ ง่ายขึ้นและยืดหยุ่นมากขึ้นได้อย่างไร ที่นี่เราแค่ต้องส่งชื่อโปเกมอนเพิ่มเติมเพื่อดึงข้อมูลเพื่อใช้ useRequest
และจัดการทุกอย่างให้เรา
ฉันหวังว่าคุณจะเริ่มเพลิดเพลินกับห้องสมุดสุดเจ๋งนี้ — อย่างไรก็ตาม เรายังมีสิ่งที่จะค้นพบเพราะ SWR มีคุณสมบัติมากมาย และหนึ่งในนั้นคือ useSWRPages
ซึ่งเป็นส่วนเกี่ยวสำหรับการแบ่งหน้าข้อมูลอย่างง่ายดาย ลองใช้เบ็ดนั้นในโครงการ
แบ่งหน้าข้อมูลของเราด้วย useSWRPages
SWR ช่วยให้เราสามารถแบ่งหน้าข้อมูลได้อย่างง่ายดายและขอเพียงบางส่วนเท่านั้น และเมื่อจำเป็นให้ดึงข้อมูลเพื่อแสดงในหน้าถัดไป
ตอนนี้ มาสร้างไฟล์ใหม่ในรูทของโปรเจ็ usePagination.js
และใช้เป็นฮุคแบบกำหนดเองสำหรับการแบ่งหน้า
import React from 'react' import useSWR, { useSWRPages } from 'swr' import { Pokemon } from './components/Pokemon' export const usePagination = (path) => { const { pages, isLoadingMore, loadMore, isReachingEnd } = useSWRPages( 'pokemon-page', ({ offset, withSWR }) => { const url = offset || `https://pokeapi.co/api/v2${path}` const { data: result, error } = withSWR(useSWR(url)) if (error) return <h1>Something went wrong!</h1> if (!result) return <h1>Loading...</h1> return result.results.map((pokemon) => ( <Pokemon key={pokemon.name} pokemon={pokemon} /> )) }, (SWR) => SWR.data.next, [] ) return { pages, isLoadingMore, loadMore, isReachingEnd } }
อย่างที่คุณเห็น เราเริ่มต้นด้วยการนำเข้า useSWRPages
ซึ่งเป็นตัวช่วยที่ช่วยให้สามารถแบ่งหน้าข้อมูลได้อย่างง่ายดาย ได้รับ 4 อาร์กิวเมนต์: คีย์ของหน้าคำขอ pokemon-page
ซึ่งใช้สำหรับการแคชด้วย, ฟังก์ชันเพื่อดึงข้อมูลที่ส่งคืนส่วนประกอบหากดึงข้อมูลสำเร็จ และฟังก์ชันอื่นที่ใช้วัตถุ SWR
และขอข้อมูลจาก หน้าถัดไป และอาร์เรย์ของการพึ่งพา
และเมื่อดึงข้อมูลแล้ว ฟังก์ชัน useSWRPages
จะคืนค่าหลายค่า แต่ที่นี่เราต้องการ 4 ค่า ได้แก่ pages
เป็นส่วนประกอบที่ส่งคืนพร้อมกับข้อมูล ฟังก์ชัน isLoadingMore
ซึ่งจะตรวจสอบว่ามีการดึงข้อมูลอยู่หรือไม่ ฟังก์ชัน loadMore
ที่ช่วยดึงข้อมูล ข้อมูลมากขึ้น และวิธีการ isReachingEnd
ซึ่งกำหนดว่ายังมีข้อมูลให้ดึงหรือไม่
ตอนนี้ เรามี hook แบบกำหนดเองที่คืนค่าที่จำเป็นเพื่อแบ่งหน้าข้อมูล ตอนนี้เราสามารถย้ายไปที่ไฟล์ App.js
และปรับแต่งได้เล็กน้อย
import React from 'react' import { usePagination } from './usePagination' import './styles.css' export default function App() { const { pages, isLoadingMore, loadMore, isReachingEnd } = usePagination( '/pokemon' ) return ( <main className='App'> <h1>Pokedex</h1> <div>{pages}</div> <button onClick={loadMore} disabled={isLoadingMore || isReachingEnd} > Load more... </button> </main> ) }
เมื่อนำเข้า hook usePagination
ตอนนี้เราสามารถส่งพา ธ เป็นพารามิเตอร์และรับค่าที่ส่งคืนได้ และเนื่องจาก pages
เป็นส่วนประกอบ เราจึงไม่จำเป็นต้องวนซ้ำข้อมูลหรืออะไรทำนองนั้น
ต่อไป เราใช้ฟังก์ชัน loadMore
บนปุ่มเพื่อดึงข้อมูลเพิ่มเติมและปิดใช้งานหากการดำเนินการดึงข้อมูลไม่เสร็จสิ้นหรือหากไม่มีข้อมูลให้ดึงข้อมูล
ยอดเยี่ยม! ด้วยการเปลี่ยนแปลงนั้น ตอนนี้เราสามารถเรียกดูบนรูทของโปรเจ็กต์และเริ่มต้นเซิร์ฟเวอร์ด้วยคำสั่งนี้เพื่อดูตัวอย่างแอปของเรา
yarn start
หรือถ้าคุณใช้ npm:
npm start
คุณควรเห็นว่าดึงข้อมูลสำเร็จแล้ว และหากคุณคลิกที่ปุ่ม SWR จะดึงข้อมูลใหม่
จนถึงตอนนี้ เราได้เห็นไลบรารี SWR ในทางปฏิบัติแล้ว และฉันหวังว่าคุณจะพบคุณค่ากับมัน อย่างไรก็ตาม มันยังคงมีคุณสมบัติบางอย่างที่จะนำเสนอ มาดูฟังก์ชันเหล่านี้กันในหัวข้อถัดไป
คุณสมบัติอื่นๆ ของ SWR
ไลบรารี SWR มีสิ่งอำนวยความสะดวกมากมายที่ช่วยให้เราสร้างแอป React ได้ง่ายขึ้น
การตรวจสอบโฟกัสใหม่
เป็นคุณลักษณะที่ช่วยให้อัปเดตหรือตรวจสอบความถูกต้องอีกครั้งเพื่อให้ข้อมูลแม่นยำยิ่งขึ้นเมื่อคุณปรับโฟกัสหน้าเว็บใหม่หรือสลับไปมาระหว่างแท็บต่างๆ และโดยค่าเริ่มต้น ฟังก์ชันนี้จะถูกเปิดใช้งาน แต่คุณสามารถปิดใช้งานได้ต่อไปหากไม่เหมาะกับความต้องการของคุณ อาจมีประโยชน์โดยเฉพาะอย่างยิ่งถ้าคุณมีข้อมูลที่มีการอัพเดตความถี่สูง
เรียกข้อมูลตามช่วงเวลา
ไลบรารี SWR อนุญาตให้ดึงข้อมูลหลังจากระยะเวลาหนึ่ง อาจมีประโยชน์เมื่อข้อมูลของคุณเปลี่ยนแปลงด้วยความเร็วสูงหรือคุณจำเป็นต้องส่งคำขอใหม่เพื่อรับข้อมูลใหม่จากฐานข้อมูลของคุณ
การกลายพันธุ์ในท้องถิ่น
ด้วย SWR คุณสามารถตั้งค่าสถานะภายในเครื่องชั่วคราวที่จะอัปเดตโดยอัตโนมัติเมื่อมีการดึงข้อมูลใหม่ (การตรวจสอบซ้ำ) คุณลักษณะนี้มีให้ใช้งานโดยเฉพาะอย่างยิ่งเมื่อคุณจัดการกับแนวทางออฟไลน์ก่อน ซึ่งจะช่วยอัปเดตข้อมูลได้อย่างง่ายดาย
เลื่อนตำแหน่งการกู้คืน
คุณลักษณะนี้มีประโยชน์มาก โดยเฉพาะอย่างยิ่งเมื่อต้องจัดการกับรายการขนาดใหญ่ ช่วยให้คุณสามารถกู้คืนตำแหน่งการเลื่อนหลังจากกลับมาที่หน้า และไม่ว่าในกรณีใด มันจะเพิ่มความสามารถในการใช้งานแอปของคุณ
การดึงข้อมูลขึ้นอยู่กับ
SWR ให้คุณดึงข้อมูลที่ขึ้นอยู่กับข้อมูลอื่น ซึ่งหมายความว่าสามารถดึงข้อมูล A ได้ และเมื่อดำเนินการเสร็จสิ้น จะใช้เพื่อดึงข้อมูล B ในขณะที่หลีกเลี่ยงน้ำตก และคุณสมบัตินี้ช่วยคุณได้เมื่อคุณมีข้อมูลเชิงสัมพันธ์
ที่กล่าวว่า SWR ช่วยเพิ่มประสบการณ์ผู้ใช้ในเรื่องใด ๆ มีคุณลักษณะมากกว่านั้น และในหลายกรณี ควรใช้ผ่าน Fetch API หรือไลบรารี Axios
บทสรุป
ตลอดบทความนี้ เราได้เห็นแล้วว่าเหตุใด SWR จึงเป็นห้องสมุดที่ยอดเยี่ยม อนุญาตให้ดึงข้อมูลระยะไกลโดยใช้ React Hooks และช่วยให้ฟีเจอร์ขั้นสูงบางอย่างง่ายขึ้น เช่น การแบ่งหน้า การแคชข้อมูล การดึงข้อมูลตามช่วงเวลา การกู้คืนตำแหน่งการเลื่อน และอื่นๆ SWR เป็นแบ็กเอนด์ที่ไม่เชื่อเรื่องพระเจ้าซึ่งหมายความว่าสามารถดึงข้อมูลจาก API หรือฐานข้อมูลประเภทใดก็ได้ สรุปแล้ว SWR ช่วยเพิ่มประสบการณ์ผู้ใช้แอป React ของคุณอย่างมาก มันมีอนาคตที่สดใส และคุณควรจับตาดูมันหรือใช้มันให้ดีขึ้นในแอป React ถัดไปของคุณ
คุณสามารถดูตัวอย่างโครงการที่เสร็จสิ้นแล้วได้ที่นี่
ขอบคุณที่อ่าน!
ขั้นตอนถัดไป
คุณสามารถตรวจสอบลิงก์ต่อไปนี้ได้ ซึ่งจะช่วยให้คุณเข้าใจมากขึ้นนอกเหนือจากขอบเขตของบทช่วยสอนนี้
- SWR
- เอกสาร SWR
อ่านเพิ่มเติม เกี่ยวกับ SmashingMag:
- ส่วนประกอบการจัดแต่งใน React
- ตัวลดที่ดีขึ้นด้วย Immer
- ส่วนประกอบที่มีลำดับสูงกว่าใน React
- การสร้างส่วนประกอบ React แบบใช้ซ้ำได้โดยใช้ Tailwind