React Native
...
Data objects
React Native: GraphQL CRUD mit Relay - Entwicklerleitfaden
16 min
react native graphql crud tutorial einführung die verwaltung von daten auf back4app mit graphql ist eine leistungsstarke option für jede art von anwendung, die abfragen beschleunigt und die komplexesten vereinfacht back4app verwendet gängige konventionen für die graphql konfiguration und bietet großartige werkzeuge, um ihre umgebung für die entwicklung einzurichten in diesem leitfaden lernen sie, wie sie grundlegende datenoperationen durch eine crud beispielanwendung durchführen, die ihnen zeigt, wie sie daten von ihrer parse server datenbank in react native mit graphql und relay erstellen, lesen, aktualisieren und löschen zuerst erstellen sie ihre komponentenfunktionen für jede crud operation, die sie später in einem vollständigen bildschirmlayout verwenden, was zu einer to do listen app führt jederzeit können sie auf dieses projekt über unsere github repositories zugreifen, um die stile und den vollständigen code zu überprüfen javascript beispiel repository voraussetzungen für dieses tutorial verwenden wir den parse server in der version 4 4 wenn sie andere versionen verwenden möchten, können sie den entsprechenden mutationscode unter https //www back4app com/docs/parse graphql/graphql logout mutation beispiel für ihre jeweilige version eine react native app, die erstellt und mit back4app verbunden ist; schließen sie das relay umgebungs setup tutorial gutes verständnis des relay stores und des relay connection updaters; sie können mehr darüber lesen unter relay modern docs wir werden javascript als standardimplementierung verwenden ziel um eine grundlegende crud anwendung in react native mit parse, graphql und relay zu erstellen 1 erstellen der todo klasse in diesem ersten schritt müssen wir die klasse definieren, mit der die anwendung arbeiten wird die todo todo klasse muss nur ein titel( string string ) feld haben, das die aufgabe beschreibt, und ein erledigt( boolean boolean ) feld, das angibt, ob die aufgabe abgeschlossen ist sie können eine generische mutation verwenden, um die klasse in ihrer datenbank zu erstellen, wenn sie sie nicht haben, indem sie unserem leitfaden im graphql cookbook https //www back4app com/docs/parse graphql/graphql mutation create object sie können die klasse auch über das dashboard von back4app erstellen, über den datenbankbrowser selbst oder von den js oder graphql konsolen nachdem sie diese neue klasse erstellt haben, denken sie daran, die schema json schema json datei vom dashboard herunterzuladen und in ihrer anwendung im data data verzeichnis zu speichern dies ist notwendig, damit der relay compiler die typen aus abfragen, mutationen usw automatisch generieren kann an diesem punkt wird ihr back4app dashboard automatisch crud mutationen für das klassenobjekt generiert haben um sie zu sehen, können sie zur graphql konsole gehen, den reiter „docs“ öffnen und nach todo todo 2 abfragen und rendern der objekte lass uns jetzt eine komponente erstellen, die für die abfrage der liste im back4app server verantwortlich ist, eine verbindung zu den objekten herstellt und die listeninhalte automatisch rendert und aktualisiert, während sie sich ändern erstelle eine neue datei mit dem namen todolistqueryrenderer js todolistqueryrenderer js in deinem src src verzeichnis mit dem folgenden code 1 import react from 'react'; 2 import { view, text } from 'react native'; 3 import { graphql, queryrenderer } from 'react relay'; 4	 5 // prerequisite properly configured relay environment 6 import environment from ' / /relay/environment'; 7	 8 // this will be created in the next steps 9 import todolist from ' /todolist'; 10	 11 const todolistqueryrenderer = () => { 12 return ( 13 // the queryrenderer acts as a wrapper to any code, providing query results to 14 // the child components and updating them as needed 15 // note that the query is using a fragment called todolist query, 16 // which will be created in the next steps 17 \<queryrenderer 18 environment={environment} 19 query={graphql` 20 query todolistqueryrendererquery { 21 todolist query 22 } 23 `} 24 variables={null} 25 render={({ error, props }) => { 26 if (error) { 27 return ( 28 \<view> 29 \<text>{error message}\</text> 30 \</view> 31 ); 32 } else if (props) { 33 return \<todolist query={props} />; 34 } 35 return ( 36 \<view> 37 \<text>loading \</text> 38 \</view> 39 ); 40 }} 41 /> 42 ); 43 } 44	 45 export default todolistqueryrenderer; 3 erstellen sie die listenkomponente und fragment des objekts lassen sie uns jetzt unsere listenkomponente erstellen, die die daten rendert, die vom queryrenderer abgerufen wurden die komponente wird vorerst nur eine einfache scrollansicht enthalten, die eine kartenfunktion enthält, die jeden knoten rendert erstellen sie eine neue datei in ihrem src verzeichnis mit dem namen todolist js todolist js und fügen sie den folgenden code hinzu 1 import react, {usestate} from 'react'; 2 import { 3 view, 4 safeareaview, 5 image, 6 scrollview, 7 statusbar, 8 stylesheet, 9 touchableopacity, 10 } from 'react native'; 11	 12 import { 13 list, 14 text as papertext, 15 button as paperbutton, 16 textinput as papertextinput, 17 } from 'react native paper'; 18 import {createfragmentcontainer} from 'react relay'; 19	 20 const todolist = props => { 21 const \[newtodotitle, setnewtodotitle] = usestate(''); 22	 23 const {query} = props; 24 const {todos} = query; 25	 26 const rendertodos = () => { 27 if (!todos) { 28 return null; 29 } 30	 31 return todos edges map(({node todo}) => ( 32 \<list item 33 key={todo id} 34 title={todo title} 35 titlestyle={todo done ? styles todo text done styles todo text} 36 style={styles todo item} 37 right={props => ( 38 <> 39 {!todo done && ( 40 \<touchableopacity onpress={() => updatetodo(todo id, true)}> 41 \<list icon { props} icon="check" color={'#4caf50'} /> 42 \</touchableopacity> 43 )} 44	 45 \<touchableopacity onpress={() => deletetodo(todo id)}> 46 \<list icon { props} icon="close" color={'#ef5350'} /> 47 \</touchableopacity> 48 \</> 49 )} 50 /> 51 )); 52 }; 53	 54 return ( 55 <> 56 \<statusbar backgroundcolor="#208aec" /> 57 \<safeareaview style={styles container}> 58 \<view style={styles header}> 59 \<papertext style={styles header text bold}> 60 {'react native on back4app'} 61 \</papertext> 62 \<papertext style={styles header text}>{'product creation'}\</papertext> 63 \</view> 64 \<view style={styles create todo container}> 65 \</view> 66 \<scrollview style={styles todo list}>{rendertodos()}\</scrollview> 67 \</safeareaview> 68 \</> 69 ); 70 }; 71	 72 const todolistfragmentcontainer = createfragmentcontainer(todolist, { 73 query graphql` 74 fragment todolist query on query { 75 todos(first 50) @connection(key "todolist todos", filters \[]) { 76 edges { 77 node { 78 id 79 title 80 done 81 } 82 } 83 } 84 } 85 `, 86 }); der abfrage renderer in schritt 2 erwartet ein datenfragment mit dem namen todolist query todolist query , also haben wir es auch am ende der datei zur listenkomponente hinzugefügt denken sie daran, dass graphql fragmente strukturen sind, die dafür verantwortlich sind, die daten abzurufen, die die komponenten zum rendern benötigen, und anzugeben, was zurückgegeben werden muss 4 objekte erstellen der erste schritt, um ihre daten in ihrer back4app graphql datenbank zu verwalten, besteht darin, einige davon zu haben wir müssen eine funktion erstellen, um einen neuen todo todo in unserer listenkomponente mithilfe einer dafür verantwortlichen mutation zu erstellen lassen sie uns mit der mutation beginnen, also erstellen sie eine neue datei mit dem namen createtodomutation js createtodomutation js im src/mutations src/mutations verzeichnis, die den folgenden code enthält 1 import { commitmutation, graphql } from "react relay"; 2 import { root id, connectionhandler } from 'relay runtime'; 3	 4 const connectioncreateedgeupdater = (store, nodeid) => { 5 const parentproxy = store get(root id); 6 const todoconnection = connectionhandler getconnection(parentproxy, 'todolist todos'); 7	 8 const newtodo = store get(nodeid); 9 const edge = connectionhandler createedge(store, todoconnection, newtodo, 'todoedge'); 10 11 // no cursor provided, append the edge at the end 12 connectionhandler insertedgeafter(todoconnection, edge); 13 } 14	 15 const mutation = graphql` 16 mutation createtodomutation($input createtodoinput!) { 17 createtodo(input $input) { 18 todo { 19 id 20 title 21 done 22 } 23 } 24 } 25 `; 26	 27 function commit({ environment, input, oncompleted, onerror }) { 28 const variables = { input }; 29	 30 commitmutation(environment, { 31 mutation, 32 variables, 33 oncompleted, 34 onerror, 35 updater (store) => { 36 const todoid = store getrootfield('createtodo') getlinkedrecord('todo') getvalue('id'); 37	 38 connectioncreateedgeupdater(store, todoid) 39 } 40 }); 41 } relay modern bietet uns eine reihe von api endpunkten, die verwendet werden können, um die daten nach mutationsaufrufen zu aktualisieren in dieser funktion haben wir einige seiner funktionen verwendet, um das neue todo todo zu erstellen und die bereits vorhandene liste im frontend zu aktualisieren mit diesem ansatz vermeiden wir einen neuen aufruf an das backend, was zeit spart, die sonst für eine neue anfrage, die internetverbindung des benutzers, übermäßiges abrufen und mehr aufgewendet würde fügen sie jetzt die folgende funktion zum todolist todolist komponente hinzu, die die createtodomutation createtodomutation aufruft und später von einem button referenziert wird 1 const createtodo = () => { 2 const input = { 3 fields { 4 title newtodotitle, 5 done false, 6 }, 7 }; 8	 9 createtodomutation commit({ 10 environment, 11 input input, 12 oncompleted () => { 13 alert alert('success!', 'todo created!'); 14 setnewtodotitle(''); 15 }, 16 onerror (errors) => { 17 alert alert('error!', errors); 18 }, 19 }); 20 } 5 aktualisierung der objekte die aktualisierung eines objekts ähnelt der erstellung, mit dem zusatz, dass sie beim aktualisieren eines objekts mit relay modern nur die felder anfordern müssen, die sie mit dem neuen zustand im ergebnis der mutation aktualisieren möchten erstellen sie eine neue datei mit dem namen updatetodomutation js updatetodomutation js im src/mutations src/mutations verzeichnis, das den folgenden code enthält 1 import { commitmutation, graphql } from "react relay"; 2	 3 const mutation = graphql` 4 mutation updatetodomutation($input updatetodoinput!) { 5 updatetodo(input $input) { 6 todo { 7 id 8 title 9 done 10 } 11 } 12 } 13 `; 14	 15 function commit({ environment, input, oncompleted, onerror }) { 16 const variables = { input }; 17	 18 commitmutation(environment, { 19 mutation, 20 variables, 21 oncompleted, 22 onerror, 23 }); 24 } 25	 26 export default { 27 commit, 28 }; genau wie im vorherigen schritt fügen sie die folgende funktion zum todolist todolist komponente hinzu, die die updatetodomutation updatetodomutation aufruft und später von einem button referenziert wird 1 const updatetodo = (todoid, done) => { 2 const input = { 3 id todoid, 4 fields { 5 done, 6 } 7 } 8	 9 updatetodomutation commit({ 10 environment, 11 input input, 12 oncompleted () => { 13 alert alert('success!', 'todo updated!'); 14 }, 15 onerror (errors) => { 16 alert alert('error!', errors); 17 }, 18 }); 19 } 6 löschen der objekte wenn sie ein objekt löschen, können sie mit den relay store apis die liste aktualisieren und das alte objekt von der benutzeroberfläche entfernen wir werden einen updater callback aufrufen, ähnlich wie das update von createtodo createtodo , aber wir werden die verbindung und die id des zu löschenden to dos übergeben, um es aus der liste zu entfernen auf diese weise halten wir die benutzeroberfläche treu zu unserem server aktualisiert erstellen sie eine neue datei mit dem namen deletetodomutation js deletetodomutation js im src/mutations src/mutations verzeichnis, die den folgenden code enthält 1 import { commitmutation, graphql } from "react relay"; 2 import { root id, connectionhandler } from 'relay runtime'; 3	 4 const connectiondeleteedgeupdater = (store, nodeid) => { 5 const parentproxy = store get(root id); 6 const connection = connectionhandler getconnection(parentproxy, 'todolist todos'); 7	 8 const newcount = connection getvalue('count'); 9 connection setvalue(newcount 1, 'count'); 10	 11 connectionhandler deletenode(connection, nodeid); 12 } 13	 14 const mutation = graphql` 15 mutation deletetodomutation($input deletetodoinput!) { 16 deletetodo(input $input) { 17 todo { 18 id 19 } 20 } 21 } 22 `; 23	 24 function commit({ environment, input, oncompleted, onerror }) { 25 const variables = { input }; 26	 27 commitmutation(environment, { 28 mutation, 29 variables, 30 oncompleted, 31 onerror, 32 updater (store) => { 33 connectiondeleteedgeupdater(store, input id) 34 } 35 }); 36 } 37	 38 export default { 39 commit, 40 }; genau wie im vorherigen schritt fügen sie die folgende funktion in die todolist todolist komponente ein, die die deletetodomutation deletetodomutation aufruft und später von einem button referenziert wird 1 const deletetodo = (todoid) => { 2 const input = { 3 id todoid, 4 } 5	 6 deletetodomutation commit({ 7 environment, 8 input input, 9 oncompleted () => { 10 alert alert('success!', 'todo deleted!'); 11 }, 12 onerror (errors) => { 13 alert alert('error!', errors); 14 }, 15 }); 16 } 7 verwendung von crud in einer react native komponente lass uns jetzt unseren todolist todolist komponenten code mit den gestalteten benutzeroberflächenelementen, zustandsvariablen und aufrufen deiner crud funktionen vervollständigen 1 import react, {usestate} from 'react'; 2 import { 3 alert, 4 view, 5 safeareaview, 6 image, 7 scrollview, 8 statusbar, 9 stylesheet, 10 touchableopacity, 11 } from 'react native'; 12	 13 import { 14 list, 15 text as papertext, 16 button as paperbutton, 17 textinput as papertextinput, 18 } from 'react native paper'; 19 import {createfragmentcontainer} from 'react relay'; 20 import createtodomutation from ' /mutations/createtodomutation'; 21 import updatetodomutation from ' /mutations/updatetodomutation'; 22 import deletetodomutation from ' /mutations/deletetodomutation'; 23	 24 import environment from ' / /relay/environment'; 25	 26 const todolist = props => { 27 const \[newtodotitle, setnewtodotitle] = usestate(''); 28	 29 const {query} = props; 30 const {todos} = query; 31	 32 const createtodo = () => { 33 const input = { 34 fields { 35 title newtodotitle, 36 done false, 37 }, 38 }; 39	 40 createtodomutation commit({ 41 environment, 42 input input, 43 oncompleted () => { 44 alert alert('success!', 'todo created!'); 45 setnewtodotitle(''); 46 }, 47 onerror errors => { 48 alert alert('error!', errors); 49 }, 50 }); 51 }; 52	 53 const updatetodo = (todoid, done) => { 54 const input = { 55 id todoid, 56 fields { 57 done, 58 }, 59 }; 60	 61 updatetodomutation commit({ 62 environment, 63 input input, 64 oncompleted () => { 65 alert alert('success!', 'todo updated!'); 66 }, 67 onerror errors => { 68 alert alert('error!', errors); 69 }, 70 }); 71 }; 72	 73 const deletetodo = todoid => { 74 const input = { 75 id todoid, 76 }; 77	 78 deletetodomutation commit({ 79 environment, 80 input input, 81 oncompleted () => { 82 alert alert('success!', 'todo deleted!'); 83 }, 84 onerror errors => { 85 alert alert('error!', errors); 86 }, 87 }); 88 }; 89	 90 const rendertodos = () => { 91 if (!todos) { 92 return null; 93 } 94	 95 return todos edges map(({node todo}) => ( 96 \<list item 97 key={todo id} 98 title={todo title} 99 titlestyle={todo done ? styles todo text done styles todo text} 100 style={styles todo item} 101 right={props => ( 102 <> 103 {!todo done && ( 104 \<touchableopacity onpress={() => updatetodo(todo id, true)}> 105 \<list icon { props} icon="check" color={'#4caf50'} /> 106 \</touchableopacity> 107 )} 108	 109 \<touchableopacity onpress={() => deletetodo(todo id)}> 110 \<list icon { props} icon="close" color={'#ef5350'} /> 111 \</touchableopacity> 112 \</> 113 )} 114 /> 115 )); 116 }; 117	 118 return ( 119 <> 120 \<statusbar backgroundcolor="#208aec" /> 121 \<safeareaview style={styles container}> 122 \<view style={styles header}> 123 \<image 124 style={styles header logo} 125 source={ { 126 uri 127 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png', 128 } } 129 /> 130 \<papertext style={styles header text bold}> 131 {'react native on back4app'} 132 \</papertext> 133 \<papertext style={styles header text}>{'product creation'}\</papertext> 134 \</view> 135 \<view style={styles create todo container}> 136 {/ todo create text input /} 137 \<papertextinput 138 value={newtodotitle} 139 onchangetext={text => setnewtodotitle(text)} 140 label="new todo" 141 mode="outlined" 142 style={styles create todo input} 143 /> 144 {/ todo create button /} 145 \<paperbutton 146 onpress={() => createtodo()} 147 mode="contained" 148 icon="plus" 149 color={'#208aec'} 150 style={styles create todo button}> 151 {'add'} 152 \</paperbutton> 153 \</view> 154 \<scrollview style={styles todo list}>{rendertodos()}\</scrollview> 155 \</safeareaview> 156 \</> 157 ); 158 }; 159	 160 const todolistfragmentcontainer = createfragmentcontainer(todolist, { 161 query graphql` 162 fragment todolist query on query { 163 todos(first 1000) @connection(key "todolist todos", filters \[]) { 164 edges { 165 node { 166 id 167 title 168 done 169 } 170 } 171 } 172 } 173 `, 174 }); 175	 176 const styles = stylesheet create({ 177 container { 178 flex 1, 179 backgroundcolor '#fff', 180 }, 181 wrapper { 182 width '90%', 183 alignself 'center', 184 }, 185 header { 186 alignitems 'center', 187 paddingtop 10, 188 paddingbottom 20, 189 backgroundcolor '#208aec', 190 }, 191 header logo { 192 width 170, 193 height 40, 194 marginbottom 10, 195 resizemode 'contain', 196 }, 197 header text bold { 198 color '#fff', 199 fontsize 14, 200 fontweight 'bold', 201 }, 202 header text { 203 margintop 3, 204 color '#fff', 205 fontsize 14, 206 }, 207 flex between { 208 flexdirection 'row', 209 alignitems 'center', 210 justifycontent 'space between', 211 }, 212 create todo container { 213 flexdirection 'row', 214 paddingleft 10, 215 paddingright 10, 216 }, 217 create todo input { 218 flex 1, 219 height 38, 220 marginbottom 16, 221 backgroundcolor '#fff', 222 fontsize 14, 223 }, 224 create todo button { 225 margintop 6, 226 marginleft 15, 227 height 40, 228 }, 229 todo list { 230 paddingleft 10, 231 paddingright 10, 232 }, 233 todo item { 234 borderbottomwidth 1, 235 borderbottomcolor 'rgba(0, 0, 0, 0 12)', 236 }, 237 todo text { 238 fontsize 15, 239 }, 240 todo text done { 241 color 'rgba(0, 0, 0, 0 3)', 242 fontsize 15, 243 textdecorationline 'line through', 244 }, 245 }); 246	 247 export default todolistfragmentcontainer; bevor sie ihr projekt ausführen, vergessen sie nicht, yarn relay yarn relay auszuführen und die relay generated generated typen zu aktualisieren wenn ihre komponente richtig eingerichtet ist, sollten sie nach dem erstellen und ausführen der app etwas wie dies sehen fügen sie einige to dos hinzu, indem sie die titel nacheinander in das eingabefeld eingeben und die schaltfläche hinzufügen drücken beachten sie, dass nach jeder erfolgreichen erstellung die createtodo createtodo funktion den aktualisierungs callback in die mutation auslöst, wodurch ihre aufgabenliste automatisch aktualisiert wird sie sollten jetzt eine umfangreiche to do liste wie diese haben sie können jetzt ihre aufgaben als erledigt markieren, indem sie auf das häkchen daneben klicken, wodurch der wert für erledigt auf wahr aktualisiert wird und sich der status des symbols links ändert wie im schritt der aktualisierungsfunktion gesagt, wird das relay automatisch die to do liste mit dem neuen wert des feldes erledigt erledigt die einzige verbleibende datenoperation ist jetzt die löschoperation, die durchgeführt werden kann, indem sie auf das mülleimer symbol ganz rechts in ihrem to do listenobjekt klicken nach erfolgreichem löschen eines objekts sollten sie eine warnmeldung wie diese erhalten fazit am ende dieses leitfadens haben sie gelernt, wie man grundlegende datenoperationen (crud) mit graphql und relay modern in react native durchführt, während sie auch die relay connection apis kennengelernt haben, die uns helfen, unser frontend zu aktualisieren