React Native
...
Data objects
Guida CRUD con GraphQL e Relay in React Native
16 min
tutorial crud graphql con react native introduzione gestire i dati su back4app utilizzando graphql è un'opzione potente per qualsiasi tipo di applicazione, accelerando le query e semplificando quelle più complesse back4app utilizza convenzioni comuni per la configurazione di graphql e fornisce ottimi strumenti per aiutare la configurazione del tuo ambiente di sviluppo in questa guida, imparerai come eseguire operazioni di base sui dati attraverso un'app di esempio crud, che ti mostrerà come creare, leggere, aggiornare e eliminare dati dal tuo database del server parse in react native utilizzando graphql e relay inizialmente creerai le funzioni dei componenti per ciascuna operazione crud, utilizzandole successivamente in un layout di schermo completo, risultando in un'app per la lista delle cose da fare in qualsiasi momento, puoi accedere a questo progetto tramite i nostri repository github per controllare gli stili e il codice completo repository di esempio javascript prerequisiti per questo tutorial utilizzeremo il server parse nella versione 4 4 se desideri utilizzare altre versioni, puoi controllare il codice di mutazione corrispondente a https //www back4app com/docs/parse graphql/graphql logout mutation esempio per la tua rispettiva versione un'app react native creata e connessa a back4app; concludere il tutorial di configurazione dell'ambiente relay buona comprensione di relay store e relay connection updater; puoi leggere di più su documentazione di relay modern utilizzeremo javascript come implementazione predefinita obiettivo costruire un'applicazione crud di base in react native utilizzando parse, graphql e relay 1 creazione della classe todo in questo primo passaggio, dobbiamo definire la classe con cui l'applicazione opererà la todo todo classe deve avere solo un campo titolo ( string string ) che descrive il compito e un campo done ( boolean boolean ) che indica se il compito è completato puoi utilizzare una mutazione generica per creare la classe nel tuo database se non ce l'hai, seguendo la nostra guida nel graphql cookbook https //www back4app com/docs/parse graphql/graphql mutation create object puoi anche creare la classe utilizzando il dashboard di back4app, attraverso il browser del database stesso o dalle console js o graphql dopo aver creato questa nuova classe, ricorda di scaricare il schema json schema json file dal dashboard e salvarlo nella tua applicazione all'interno della data data directory questo è necessario affinché il relay compiler generi automaticamente i tipi da query, mutazioni, ecc a questo punto, il tuo dashboard di back4app avrà generato automaticamente le mutazioni crud per l'oggetto classe, per vederle puoi andare nella console graphql, aprire la scheda documenti e cercare todo todo 2 interrogazione e rendering degli oggetti creiamo ora un componente che sarà responsabile di effettuare la query della lista nel server back4app, stabilendo una connessione per gli oggetti e renderizzando e aggiornando automaticamente i contenuti della lista man mano che cambiano crea un nuovo file chiamato todolistqueryrenderer js todolistqueryrenderer js nella tua src src directory con il seguente codice 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 crea il componente list e il fragment di object creiamo ora il nostro componente lista, che renderizzerà i dati recuperati dal queryrenderer il componente conterrà per ora solo una semplice vista a scorrimento contenente una funzione di mappatura che renderizza ogni nodo procedi e crea un nuovo file nella tua directory src chiamato todolist js todolist js e aggiungi il seguente codice 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 }); il query renderer nel passo 2 si aspetta un frammento di dati chiamato todolist query todolist query , quindi lo abbiamo aggiunto anche al componente della lista alla fine del file ricorda che i frammenti graphql sono strutture responsabili della chiamata ai dati di cui i componenti hanno bisogno per essere renderizzati e specificano cosa deve essere restituito 4 creazione degli oggetti il primo passo per gestire i tuoi dati nel tuo database graphql di back4app è averne alcuni dobbiamo creare una funzione da chiamare per creare un nuovo todo todo nel nostro componente della lista utilizzando una mutazione responsabile per questo iniziamo con la mutazione, quindi crea un nuovo file chiamato createtodomutation js createtodomutation js nella directory src/mutations src/mutations contenente il seguente codice 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 ci fornisce un insieme di endpoint api da utilizzare per aggiornare i dati dopo le chiamate di mutazione in questa funzione, abbiamo utilizzato alcune delle sue funzioni per ottenere il nuovo todo todo creato e aggiornare l'elenco già esistente sul frontend con questo approccio, evitiamo una nuova chiamata al backend risparmiando tempo che sarebbe speso in una nuova richiesta, internet dell'utente, sovra recupero e altro ora aggiungi la seguente funzione al todolist todolist componente, che chiamerà il createtodomutation createtodomutation e sarà referenziato in seguito da un pulsante 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 aggiornare gli oggetti aggiornare un oggetto è simile a crearlo, con l'aggiunta che, quando si aggiorna un oggetto utilizzando relay modern, è sufficiente richiedere i campi che si desidera aggiornare con il nuovo stato sull'output della mutazione crea un nuovo file chiamato updatetodomutation js updatetodomutation js nella src/mutations src/mutations directory contenente il seguente codice 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 }; proprio come nel passaggio precedente, aggiungi la seguente funzione al todolist todolist componente, che chiamerà il updatetodomutation updatetodomutation e sarà referenziato in seguito da un pulsante 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 cancellare gli oggetti quando si cancella un oggetto, con le api del relay store è possibile aggiornare l'elenco e rimuovere il vecchio oggetto dal frontend chiameremo un callback di aggiornamento, simile all'aggiornamento da createtodo createtodo , ma passeremo la connessione e l'id del to do per rimuoverlo dall'elenco in questo modo, manteniamo il frontend fedelmente aggiornato al nostro server crea un nuovo file chiamato deletetodomutation js deletetodomutation js nella directory src/mutations src/mutations contenente il seguente codice 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 }; proprio come nel passaggio precedente, aggiungi la seguente funzione al todolist todolist componente, che chiamerà il deletetodomutation deletetodomutation e sarà referenziato in seguito da un pulsante 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 utilizzare crud in un componente react native completiamo ora il nostro todolist todolist codice del componente con gli elementi dell'interfaccia utente stilizzati, le variabili di stato e le chiamate alle tue funzioni crud 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; prima di eseguire il tuo progetto, non dimenticare di eseguire yarn relay yarn relay e aggiornare i tipi di relay generated generated se il tuo componente è configurato correttamente, dovresti vedere qualcosa del genere dopo aver costruito e avviato l'app procedi ad aggiungere alcune attività da fare digitando i loro titoli nella casella di input uno alla volta e premendo il pulsante aggiungi nota che dopo ogni creazione riuscita, la createtodo createtodo funzione attiva il callback dell'updater nella mutazione, aggiornando automaticamente la tua lista di attività ora dovresti avere una lista di attività considerevole come questa ora puoi contrassegnare le tue attività come completate facendo clic sulla casella di controllo accanto ad essa, causando l'aggiornamento del loro valore di completamento a vero e cambiando il loro stato dell'icona a sinistra come detto nel passaggio della funzione di aggiornamento, il relay aggiornerà automaticamente il todo con il nuovo valore del campo completato completato l'unica operazione sui dati rimanente è ora quella di eliminazione, che può essere eseguita premendo sull'icona del cestino all'estrema destra del tuo oggetto della lista delle attività dopo aver eliminato con successo un oggetto, dovresti ricevere un messaggio di avviso come questo conclusione alla fine di questa guida, hai imparato come eseguire operazioni di base sui dati (crud) con graphql e relay modern su react native, imparando anche le api di connessione relay che ci aiutano ad aggiornare il nostro frontend