Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Quindi usando React.js + React Native posso sviluppare app native per mobile.
4.
In pratica solo la parte di UI viene compilata; tutta la logica rimane in js e viene interpretata
da una VM che esegue in un thread dedicato all’interno dell’app
5.
Per sviluppare un’app posso usare o Expo o React Native CLI: Expo è più facile, meno
performante e meno fine-tunable, ma ottimo per iniziare. Nel caso, si può passare in un
secondo tempo a React Native CLI (‘eject’)
Javascript refresher
Arrow functions
const myFunc = (arg1, arg2) => {
return arg1 + arg2
}
Se ho solo la direttiva return nel corpo della funzione, posso omettere le graffe e la keyword
return:
const myFunc = (arg1, arg2) => arg1 + arg2
Se non ho parametri:
const myFunc = () => 5 + 10
}
return out
}
Destructuring assignment
Permette di spacchettare elementi singoli di oggetti o array
Object destructuring:
const person = { age : 22, name : 'dio', isGod : true}
printName(person)
specifico il nome degli attributi a cui sono interessato
console.log(isGod)
Nota: quando spacchetto devo mantenere i nomi degli attributi.
Array destructuring:
const cane = [1,2,3,4,5]
const [a, b, ...rest] = cane
console.log(a)
console.log(rest)
React
Component:
un component può essere:
una funzione che ritorna del JSX oppure una serie di istruzioni React.createElement
una classe che ha un metodo render che ritorna del JSX oppure una serie di istruzioni
React.createElement
Nota: posso usare JSX, oppure posso importare direttamente un css in un file .js perché
react sa parsare queste cose e produce codice js nativo. E’ per quello che devo fare
Import React from ‘react’ anche se non uso nulla dalla classe React
Nota: i file css hanno scope globale, a prescindere da dove li metto e in che file li importo;
tutti i component della mia app vedono tutti i css
goals è un array che passo come prop al functional component GoalList; per renderizzarlo ci
chiamo sopra map.
Comunicazione tra component:
Se devo passare dati dal parent component al child component li passo come props
Se devo passare dei dati da un child component al parent component invece, definisco una
callback nel parent che passo al child come prop, in cui scrivo cosa fare con i dati.
Esempio:
Il parent è App
const App = () => {
const courseGoals = [];
return (
<div className="course-goals">
<h2>Course Goals</h2>
<NewGoal onAddGoal={addNewGoalHandler} />
<GoalList goals={courseGoals} />
</div>
);
};
il Child è NewGoal
const NewGoal = props => {
const addGoalHandler = event => {
event.preventDefault();
const newGoal = {
id: Math.random().toString(),
text: 'My new goal!'
};
props.onAddGoal(newGoal);
};
return (
<form className="new-goal" onSubmit={addGoalHandler}>
<input type="text" />
<button type="submit">Add Goal</button>
</form>
);
};
In partica NewGoal renderizza un input che permette di scrivere il testo per un nuovo goal e
un bottone per salvarlo. All’evento del bottone associo addGoalHandler, che al suo interno
richiama la callback definita nel parent, accedendola attraverso le props: props.onAddGoal.
Stato
React usa lo stato per capire quando deve ri-renderizzare qualcosa: se una variabile nello
stato cambia valore, tutti i component che la usano vengono ri-renderizzati
automaticamente
React mette a disposizione funzioni specifiche per gestire lo stato, dette hook functions, che
possono essere usate solo dentro functional components. Per ogni variabile che vogliamo
inserire nello stato di un component, uso la hook function useState:
const [variable_name, set_function] = useState(intial_value).
Dove: variable_name contiene l’ultimo snapshot dello stato, e set_function è la funzione che
permette di modificarlo.
Nota: set_function prende come parametro un nuovo oggetto, non modifica quello
attualmente presente nello stato (lo sovrascrive con quello nuovo)
App lo possiamo riscrivere così:
const App = () => {
const [courseGoals, setCourseGoals] = useState([
{ id: 'cg1', text: 'Finish the Course' },
{ id: 'cg2', text: 'Learn all about the Course Main Topic' },
{ id: 'cg3', text: 'Help other students in the Course Q&A' }
]);
return (
<div className="course-goals">
<h2>Course Goals</h2>
<NewGoal onAddGoal={addNewGoalHandler} />
<GoalList goals={courseGoals} />
</div>
);
};
Nota: se il nuovo stato dipende da quello precedente, alla mia set_function devo passare
una funzione, che prende in input lo stato precedente e ne ritorna uno nuovo:
setCourseGoals(prevCourseGoals => prevCourseGoals.concat(newGoal));
Questo metodo mi assicura anche, in applicazioni con molti cambi di stato simultanei, che i
questi cambi avvengano nell’ordine corretto.
const newGoal = {
id: Math.random().toString(),
text: enteredText
};
setEnteredText('');
props.onAddGoal(newGoal);
};
return (
<form className="new-goal" onSubmit={addGoalHandler}>
<input type="text" value={enteredText} onChange={textChangeHandler} />
<button type="submit">Add Goal</button>
</form>
);
};
il campo testo ha due binding allo stato: da una parte, il suo valore è legato a quello di
enteredText, che è la variabile inserita nello stato del component. Dall’altro, quando il
valore del campo cambia viene chiamata la funzione textChangeHandler che, al suo interno,
richiama setEnteredText per modificare il valore dello stato.
Core components:
<View> è come un div
<Text> contiene del testo. Non è possibile mettere testo in un’app se non racchiuso tra i tag
<Text>
FlexBox:
utilizzato per posizionare i child elements di una view
permette di organizzare i child di una view o su una riga o su una colonna (default)
flexDirection: può essere row, column o row-reverse, column-reverse per invertire l’ordine
dei child
La flexDirectione specifica la main axis; la cross axis è l’opposto (cross axis di column è row,
cross axis di row-reverse è row-column)
se non specifico width e height dei child, occuperanno il minimo indispensabile perché il
loro contenuto possa essere visualizzato
Se specifico width e height della parent view, nel caso i child non abbiano dimensioni
specificate, assumono l’height del parent, mentre il width rimane immutato
Per organizzare i miei child lungo la main axis uso justifyContent; per organizzarli lungo la
cross axis uso alignItems
Il comportamento di default è che i child si organizzano lungo la cross axis stretchandosi; se
voglio farli stretchare anche lungo la main axis non posso usare stretch come valore di
justifyContent, ma devo agire sul singolo child: specifico l’attributo flex all’interno
dell’oggetto StyleSheet del child, e gli assegno un valore. Il valore è un numero relativo tra
tutti i child.
ScrollView component: da utilizzare al posto di una View se voglio che sia scrollabile in caso
di overflow del contenuto
Nel caso abbia già degli oggetti che non hanno un attributo ‘key’ o ‘id’ (riconosciuti da react
come indici univoci), devo passare a FlatList un keyExtractor. Supponendo che i miei oggetti
abbiamo un attributo chiave che si chiama ‘cane’, devo fare:
<FlatList
keyExtractor = {(item, index) => item.cane}
data={courseGoals}
renderItem={
itemList => {
return <View style={styles.listItem}>
<Text>{itemList.item.value}</Text>
</View>
}
}
/>
Se una callback che passo ad un component necessita di essere chiamata con un attributo,
uso il metodo bind:
const GoalItem = props => {
return (
<TouchableOpacity onPress={props.onDelete.bind(this,props.id)}>
<View style={styles.listItem}>
<Text>{props.title}</Text>
</View>
</TouchableOpacity>
)
};
3.
Debug: Per usare React Native Debugger, prima devo lanciarlo, poi sullo smartphone, in
Expo, gli dico “Debug appication”.