React Native
Relay (GraphQL)
สร้าง Query Renderer ด้วย Relay ใน React Native
27 นาที
ตัวเรนเดอร์คำถามบน back4app บทนำ ในคู่มือก่อนหน้านี้ https //www back4app com/docs/react native/graphql/relay setup , เราได้เรียนรู้วิธีการเตรียมสภาพแวดล้อม relay ของเรา ตอนนี้คุณพร้อมที่จะเริ่มพัฒนาแอป react native ของคุณแล้ว ในคู่มือนี้ คุณจะได้เรียนรู้วิธีการทำคำถามแรกของคุณบน back4app เราจะดำดิ่งสู่ตัวเรนเดอร์คำถาม relay เข้าใจหลักการหลักและใช้มันเพื่อดึงข้อมูลแรกของคุณจาก back4app เป้าหมาย รับภาพรวมของตัวเรนเดอร์คำถาม relay; ทำคำถามบน back4app graphql api จากแอป react native โดยใช้ relay; ข้อกำหนดเบื้องต้น แอปพลิเคชันที่สร้างขึ้นที่แดชบอร์ด back4app แอปพลิเคชัน react native และมีการกำหนดค่าพื้นที่ relay ตามเอกสารก่อนหน้านี้ อ่านเกี่ยวกับ relay node และ connections ตัวเรนเดอร์คำถามคืออะไร? เช่นเดียวกับที่ react สร้างต้นไม้ของส่วนประกอบ relay สร้างต้นไม้ของส่วนประกอบข้อมูล ซึ่งหมายความว่าส่วนประกอบแต่ละตัวของแอปพลิเคชันจะเป็นเจ้าของข้อมูลของแฟร็กเมนต์ของตนเอง แฟร็กเมนต์จะมีข้อมูลที่จำเป็นในการเรนเดอร์บนหน้าจอและ relay จะรับประกันว่าข้อมูลนี้พร้อมก่อนที่จะเรนเดอร์ส่วนประกอบ การจัดการแนวทางทั้งหมดนี้ ตัวเรนเดอร์คำถามเป็นส่วนประกอบรากที่จำเป็นในการประกอบแฟร็กเมนต์เหล่านั้นและเตรียมคำถามที่จะดึงจากแบ็กเอนด์ของเรา ทำไมต้องเข้าใจตัวเรนเดอร์คำถาม? การเข้าใจการใช้ตัวเรนเดอร์คำถามทำให้มันสำคัญในการทำให้แอปพลิเคชันของคุณเป็นนามธรรมในหลายวิธี การทำให้โค้ดเป็นนามธรรมที่ดีสามารถป้องกันชั่วโมงของการทำงาน ข้อผิดพลาด เวลาการดีบัก ฯลฯ วิธีการทำงานของเรนเดอร์ร่วมกับ back4app apis ในบทเรียนก่อนหน้า เราได้เตรียมไฟล์ relay environment ซึ่งระบุข้อมูลการเชื่อมต่อกับ back4app โดยใช้การกำหนดค่านี้ relay จะดูแลการสื่อสารกับ back4app apis คุณไม่ต้องกังวลเกี่ยวกับการเชื่อมต่อ เพียงแค่โฟกัสที่การสร้างส่วนประกอบข้อมูล 1 การสร้างคลาสใน back4app dashboard มาสร้างคลาสแรกของคุณและเติมมันด้วยวัตถุไม่กี่ตัวโดยใช้ back4app graphql console คลาส person มี 2 ฟิลด์ ชื่อซึ่งเป็นสตริงและเงินเดือนซึ่งเป็นจำนวนเต็ม ไปที่ dashboard >core >graphql console และใช้โค้ดด้านล่าง 1 mutation createclass { 2 createclass(input { 3 name "person" 4 schemafields { 5 addstrings \[{name "name"}] 6 addnumbers \[{name "salary"}] 7 } 8 }){ 9 class{ 10 schemafields{ 11 name 12 typename 13 } 14 } 15 } 16 } คุณจะเห็นผลลัพธ์ด้านล่าง การสร้างคลาส ตอนนี้เรามาสร้างวัตถุภายในคลาสนี้กัน ไปที่การสร้างวัตถุการเปลี่ยนแปลง https //www back4app com/docs/parse graphql/graphql mutation create object#mutation generic และดูวิธีจัดการกับกรณีนี้ให้แน่ใจว่าคุณกำลังใช้เวอร์ชัน parse server ล่าสุดเพื่อใช้การบันทึก api graphql ที่ใหม่ที่สุดที่มีอยู่ใน back4app 1 mutation createobject{ 2 createhero(input {fields {name "allana foley", salary 1000}}){ 3 person { 4 id 5 name 6 salary 7 } 8 } 9 } การสร้างวัตถุ ตอนนี้ คลาส person ถูกสร้างขึ้นและมีฟิลด์ชื่อและเงินเดือน หลังจากสร้างคลาสใหม่ back4app จะสร้างทรัพยากรที่จำเป็นทั้งหมดโดยอัตโนมัติเพื่อใช้แบ็กเอนด์อย่างปลอดภัย ตัวอย่างหนึ่งคือรายการของวัตถุ back4app ได้สร้างการเชื่อมต่อที่จำเป็นเพื่อเรียกดูรายการของบุคคล people เพื่อให้เข้าใจได้ดีขึ้น ไปที่สนามเด็กเล่น รีเฟรชและเปิดแท็บเอกสารแล้วมองหาบุคคล back4app สร้างฟิลด์การเชื่อมต่อ คุณยังสามารถเรียกดูคลาสบุคคลเป็นรายการได้ โปรดทราบว่าฟิลด์ query people เป็น personconnection relay จะใช้ฟิลด์การเชื่อมต่อเพื่อแสดงรายการของวัตถุของบุคคล เอกสารฟิลด์บุคคล และเอกสารฟิลด์การเชื่อมต่อบุคคล (person) 2 การอัปเดตสคีมา สิ่งสำคัญคือต้องจำไว้ว่าหากมีคลาสใหม่เข้าสู่แอปพลิเคชันของคุณ จะต้องอัปเดตสคีมาภายในรากของแอปพลิเคชัน react native หากจำเป็น ให้ไปที่ https //www back4app com/docs/react native/graphql/download schema เอกสารและทำซ้ำขั้นตอนเพื่ออัปเดตสคีมา 3 ตัวอย่างแรกของคอนเทนเนอร์แฟร็กเมนต์ ก่อนที่เราจะดำเนินการสอนต่อไป ให้เรานำเสนอคุณกับคอนเทนเนอร์แฟร็กเมนต์ เราจะสร้างคอมโพเนนต์ที่จะเป็นเจ้าของข้อมูลบุคคล คอมโพเนนต์นี้จะประกอบด้วยชื่อและเงินเดือนของบุคคล ที่นี่คุณสามารถขอข้อมูลฟิลด์บุคคลใด ๆ เพื่อสร้างคอมโพเนนต์ของคุณ ตอนนี้เราจะดำเนินการกับสองฟิลด์นี้ สร้างไฟล์และตั้งชื่อมันว่า personcard js personcard js ภายในนั้น ให้เราสร้างฟังก์ชันคอมโพเนนต์ที่เรียบง่าย 1 import react from 'react'; 2	 3 const personcard = () => { 4 return ( 5 \<div> 6 7 \</div> 8 ); 9 }; แทนที่บรรทัดของ export default ด้วยโค้ดด้านล่างนี้ 1 export default createfragmentcontainer(personcard, { 2 person graphql` 3 fragment personcard person on person { 4 id 5 name 6 salary 7 } 8 `, 9 }); โค้ดด้านบนจะสร้าง fragment ของ person ที่ขอเพียง id, name, และ salary เท่านั้น เสร็จสิ้นการอัปเดตส่วนที่เหลือของคอมโพเนนต์ด้วยโค้ดต่อไปนี้ 1 const personcard = ({person}) => { 2 return ( 3 \<view> 4 \<text>name {person name}\</text> 5 \<text>salary {person salary}\</text> 6 \</view> 7 ); 8 }; ผลลัพธ์สุดท้ายควรมีลักษณะดังนี้ 1 import react from "react"; 2 import { createfragmentcontainer, graphql } from "react relay"; 3 import { view, text } from "react native"; 4	 5 const personcard = ({person}) => { 6 return ( 7 \<view> 8 \<text>name {person name}\</text> 9 \<text>salary {person salary}\</text> 10 \</view> 11 ); 12 }; 13	 14 export default createfragmentcontainer(personcard, { 15 person graphql` 16 fragment personcard person on person { 17 id 18 name 19 salary 20 } 21 `, 22 }); 4 การสร้าง query renderer ขั้นตอนถัดไปคือการสร้าง query renderer สำหรับรายการวัตถุของคุณ query renderer เป็นคอมโพเนนต์หลักสำหรับการดึงข้อมูลคอมโพเนนต์และเตรียมพวกเขาเพื่อดึงข้อมูลจากแบ็คเอนด์ คุณจะได้เรียนรู้วิธีการดึงข้อมูลสำหรับคลาส person บน back4app 4 1 การสร้างไฟล์ สร้างไฟล์ใหม่และตั้งชื่อว่า personrenderer js personrenderer js คัดลอกโค้ดด้านล่างและวางลงในไฟล์ personrenderer 1 const personrenderer = () => { 2 return ( 3 \<queryrenderer 4 environment={environment} 5 query={graphql``} 6 variables={null} 7 render={({error, props}) => { 8 if (error) { 9 return ( 10 \<view> 11 \<text>{error message}\</text> 12 \</view> 13 ); 14 } else if (props) { 15 // @todo here will be implement the person card for each item from result 16 } 17 return ( 18 \<view> 19 \<text>loading\</text> 20 \</view> 21 ); 22 }} 23 /> 24 ); 25 }; 26	 27 export default personrenderer; 4 2 การเข้าใจ props ของ queryrenderer เริ่มต้นด้วย query renderer ที่มี props ว่าง graphql, variables, และ render ทีละขั้นตอน คุณจะทำการ implement แต่ละอย่างทีละน้อย ก่อนอื่น แอปพลิเคชันของคุณต้องแจ้ง query สำหรับ query renderer ที่นี่ แอปพลิเคชันของเราจะใช้รายการของ people ใน query props ให้วางโค้ดต่อไปนี้ 1 graphql` 2 query personrendererquery { 3 people { 4 edges { 5 node { 6 personcard person 7 } 8 } 9 } 10 }` graphql มาจาก react relay และทำการ query เป็น string สิ่งสำคัญคือต้องเข้าใจ edges และการเชื่อมต่อ node query ข้างต้นกำลังใช้การเชื่อมต่อ node ของผู้คนจากเซิร์ฟเวอร์ back4app ทุกครั้งที่คุณสร้างคลาสใหม่ จะมีการเชื่อมต่อ node ตามมา ตัวแปร เมื่อจำเป็น query renderer จะใช้ตัวแปร ตัวอย่างที่ดี เมื่อแอปพลิเคชันขอ query สำหรับบุคคลตาม id เนื่องจากตอนนี้ไม่ใช่กรณีนี้ ให้ส่งผ่าน null ใน props ของตัวแปร การเติมข้อมูลใน person card query นี้จะส่งคืนรายการของผู้คน query renderer จะรับประกันว่าข้อมูลจะพร้อมใช้งานสำหรับการเรนเดอร์ หากไม่เช่นนั้น จะมีการแสดงข้อผิดพลาด props ที่รับผิดชอบในเรื่องนี้คือ render เติม props render ด้วยโค้ดต่อไปนี้ 1 render={({error, props}) => { 2 if (error) { 3 return ( 4 \<view> 5 \<text>{error message}\</text> 6 \</view> 7 ); 8 } else if (props) { 9 return props people edges map(({node}) => \<personcard person={node} />); 10 } 11 return ( 12 \<view> 13 \<text>loading\</text> 14 \</view> 15 ); 16 }} แทนที่ todo ที่ถูกคอมเมนต์ด้วยการใช้ map ของ javascript เพื่อเรนเดอร์การ์ดบุคคลสำหรับแต่ละผลลัพธ์จากรายการ ตามที่กล่าวไว้ query renderer จะรับผิดชอบในการทำให้ข้อมูลพร้อมใช้งานเมื่อมันพร้อมเท่านั้น จนกว่าจะถึงตอนนั้น ข้อความกำลังโหลดจะถูกแสดง หากเกิดข้อผิดพลาด จะถูกแสดงบนหน้าจอเพื่อป้องกันไม่ให้แอปพลิเคชันเกิดการล่มโดยไม่คาดคิด สุดท้าย ให้ปรับปรุงการเรนเดอร์ของบุคคลโดยการแทนที่ map ด้วยฟังก์ชันใหม่ วางมันไว้ก่อน query renderer 1 const renderpersons = (people) => { 2 return people edges map(({node}) => \<personcard person={node} />); 3 }; และผลลัพธ์สุดท้ายควรมีลักษณะดังนี้ 1 import react from "react"; 2 import { queryrenderer } from "react relay"; 3 import environment from " /relay/environment"; 4 import personcard from " /personcard"; 5 import { view, text } from "react native"; 6	 7 const personrenderer = () => { 8 const renderpersons = (people) => { 9 return people edges map(({node}) => \<personcard person={node} />); 10 }; 11	 12 return ( 13 \<queryrenderer 14 environment={environment} 15 query={graphql` 16 query personrendererquery { 17 people { 18 edges { 19 node { 20 personcard person 21 } 22 } 23 } 24 } 25 `} 26 variables={null} 27 render={({error, props}) => { 28 if (error) { 29 return ( 30 \<view> 31 \<text>{error message}\</text> 32 \</view> 33 ); 34 } else if (props) { 35 return renderpersons(props people); 36 } 37 return ( 38 \<view> 39 \<text>loading\</text> 40 \</view> 41 ); 42 }} 43 /> 44 ); 45 }; 46	 47 export default personrenderer; 5 การทำคำถามแรกของคุณ ตอนนี้ถึงเวลาในการดึงข้อมูลบุคคลโดยใช้ personrenderer หากทุกอย่างเรียบร้อย แอปพลิเคชันของคุณตอนนี้มีส่วนประกอบใหม่สองตัว personrenderer และ personcard ก่อนเริ่มแอปพลิเคชัน relay ต้องการ relay compiler เพื่อทำงานและสร้างประเภทของส่วนประกอบ สำหรับสิ่งนี้ ให้รันในเทอร์มินัลของคุณ เส้นด้ายรีเลย์ ใน app js ให้เพิ่มโค้ดต่อไปนี้ 1 import react from 'react'; 2 import { safeareaview, statusbar, view, text } from 'react native'; 3	 4 import providers from ' /providers'; 5 import personrenderer from ' /components/home/person/personrenderer'; 6	 7 const app = () => { 8 return ( 9 \<providers> 10 \<statusbar barstyle="dark content" /> 11 \<safeareaview> 12 \<view 13 style={ { 14 flexdirection 'column', 15 justifycontent 'center', 16 alignitems 'center', 17 margintop 100, 18 } }> 19 \<text style={ {fontweight "bold", textalign "center"} }> 20 back4app react native relay query renderer list example 21 \</text> 22 \<personrenderer /> 23 \</view> 24 \</safeareaview> 25 \</providers> 26 ); 27 }; 28	 29 export default app; โค้ดของ app js มาจาก create react native app โดยตรง มันได้เพิ่ม view พร้อมสไตล์เพื่อจัดกลางเนื้อหาบนหน้าจอโดยมีระยะห่าง 10px จากด้านบน ภายในมีข้อความที่มีป้ายกำกับเพื่อให้บริบทสำหรับการพิมพ์และ personrenderer เพื่อแสดงรายการบุคคล คุณต้องการให้ได้ผลลัพธ์ดังต่อไปนี้ การเรนเดอร์ ในแอปพลิเคชัน back4app react native ของเรา เรานำเข้า personrenderer โดยตรงไปยัง app js app js เนื่องจาก personrenderer เป็นคอมโพเนนต์หลักและมี queryrenderer ของมันเอง บุคคลต้องแสดงโดยไม่มีข้อผิดพลาด 6 การพิมพ์คอมโพเนนต์ ขั้นตอนนี้มีความหมายสำหรับแอปพลิเคชันที่ทำงานกับ typescript หากแอปพลิเคชันของคุณไม่ใช้ typescript ก็ไปต่อได้เลย หนึ่งในพลังของ relay compiler คือการสร้างประเภทจากแต่ละคอมโพเนนต์ข้อมูล มาพิมพ์ personrenderer และ personcard เพื่อทำให้แอปพลิเคชันมีประสิทธิภาพมากขึ้น การพิมพ์ personrenderer พิมพ์อาร์กของฟังก์ชัน renderperson people people ลงใน personrenderer 1 const renderpersons = (people personrendererquery\['response']\['people']) => { 2 return people edges map(({node}) => \<personcard person={node} />); 3 }; นำเข้า personrendererquery personrendererquery ประเภทจาก generated generated โฟลเดอร์ที่สร้างขึ้นภายในโฟลเดอร์เดียวกันกับ personrenderer การพิมพ์ personcard ไปที่ personcard สร้างอ็อบเจ็กต์ประเภทใหม่และตั้งชื่อว่า personcardprops 1 type personcardprops = {}; นำเข้า personcard person personcard person ประเภทจาก generated generated โฟลเดอร์ 1 import {personcard person} from ' / generated /personcard person graphql'; เพิ่มบุคคลภายในประเภท personcardprops 1 type personcardprops = { 2 person personcard person; 3 }; ในอาร์กิวเมนต์ props จาก personcard ให้พิมพ์คอมโพเนนต์ด้วย personcardprops personcardprops 1 const personcard = ({person} personcardprops) => { } ผลลัพธ์สุดท้ายของทั้งสองคอมโพเนนต์ควรมีลักษณะดังนี้ personrenderer 1 import react from 'react'; 2 import {graphql, queryrenderer} from 'react relay'; 3 import {environment} from ' / / /relay'; 4 import personcard from ' /personcard'; 5 import {view, text} from 'react native'; 6 import {personrendererquery} from ' / generated /personrendererquery graphql'; 7	 8 const personrenderer = () => { 9 const renderpersons = (people personrendererquery\['response']\['people']) => { 10 return people edges map(({node}) => \<personcard person={node} />); 11 }; 12	 13 return ( 14 \<queryrenderer 15 environment={environment} 16 query={graphql` 17 query personrendererquery { 18 people { 19 edges { 20 node { 21 personcard person 22 } 23 } 24 } 25 } 26 `} 27 variables={null} 28 render={({error, props}) => { 29 if (error) { 30 return ( 31 \<view> 32 \<text>{error message}\</text> 33 \</view> 34 ); 35 } else if (props) { 36 return renderpersons(props people); 37 } 38 return ( 39 \<view> 40 \<text>loading\</text> 41 \</view> 42 ); 43 }} 44 /> 45 ); 46 }; 47	 48 export default personrenderer; personcard 1 import react from 'react'; 2	 3 import {createfragmentcontainer, graphql} from 'react relay'; 4	 5 import {view, text} from 'react native'; 6 import {personcard person} from ' / generated /personcard person graphql'; 7	 8 type personcardprops = { 9 person personcard person; 10 }; 11	 12 const personcard = ({person} personcardprops) => { 13 return ( 14 \<view> 15 \<text>name {person name}\</text> 16 \<text>salary {person salary}\</text> 17 \</view> 18 ); 19 }; 20	 21 export default createfragmentcontainer(personcard, { 22 person graphql` 23 fragment personcard person on person { 24 id 25 name 26 salary 27 } 28 `, 29 }); บทสรุป ผลลัพธ์สุดท้ายของ queryrenderer แสดงให้เห็นว่าการใช้งานสามารถทำให้เป็นนามธรรมได้ แอปพลิเคชันสามารถแสดงบุคคลภายใน query renderer ได้ เนื่องจาก personcard มีส่วนประกอบมากขึ้น จึงไม่เปลี่ยนแปลงวิธีการสร้าง query renderer personrenderer ถูกสร้างขึ้นเพื่อแสดงให้เห็นว่าการทำ query สามารถทำได้ในขั้นตอนที่ง่าย ร่วมกับพลังของเซิร์ฟเวอร์ back4app ในคู่มือต่อไป คุณจะได้เรียนรู้วิธีการดึงวัตถุบุคคลเฉพาะและแสดงคุณสมบัติของพวกเขา