feat: add 'back/front end' in curriculum (#42596)

* chore: rename APIs and Microservices to include "Backend" (#42515)

* fix typo

* fix typo

* undo change

* Corrected grammar mistake

Corrected a grammar mistake by removing a comma.

* change APIs and Microservices cert title

* update title

* Change APIs and Microservices certi title

* Update translations.json

* update title

* feat(curriculum): rename apis and microservices cert

* rename folder structure

* rename certificate

* rename learn Markdown

* apis-and-microservices -> back-end-development-and-apis

* update backend meta

* update i18n langs and cypress test

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>

* fix: add development to front-end libraries (#42512)

* fix: added-the-word-Development-to-front-end-libraries

* fix/added-the-word-Development-to-front-end-libraries

* fix/added-word-development-to-front-end-libraries-in-other-related-files

* fix/added-the-word-Development-to-front-end-and-all-related-files

* fix/removed-typos-from-last-commit-in-index.md

* fix/reverted-changes-that-i-made-to-dependecies

* fix/removed xvfg

* fix/reverted changes that i made to package.json

* remove unwanted changes

* front-end-development-libraries changes

* rename backend certSlug and README

* update i18n folder names and keys

* test: add legacy path redirect tests

This uses serve.json from the client-config repo, since we currently use
that in production

* fix: create public dir before moving serve.json

* fix: add missing script

* refactor: collect redirect tests

* test: convert to cy.location for stricter tests

* rename certificate folder to 00-certificates

* change crowdin config to recognise new certificates location

* allow translations to be used

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>

* add forwards slashes to path redirects

* fix cypress path tests again

* plese cypress

* fix: test different challenge

Okay so I literally have no idea why this one particular challenge
fails in Cypress Firefox ONLY. Tom and I paired and spun a full build
instance and confirmed in Firefox the page loads and redirects as
expected. Changing to another bootstrap challenge passes Cypress firefox
locally. Absolutely boggled by this.

AAAAAAAAAAAAAAA

* fix: separate the test

Okay apparently the test does not work unless we separate it into
a different `it` statement.

>:( >:( >:( >:(

Co-authored-by: Sujal Gupta <55016909+heysujal@users.noreply.github.com>
Co-authored-by: Noor Fakhry <65724923+NoorFakhry@users.noreply.github.com>
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>
This commit is contained in:
Shaun Hamilton
2021-08-14 03:57:13 +01:00
committed by GitHub
parent 4df2a0c542
commit c2a11ad00d
1215 changed files with 790 additions and 449 deletions

View File

@ -0,0 +1,165 @@
---
id: 5a24c314108439a4d403616e
title: Accedere alle proprietà utilizzando this.props
challengeType: 6
forumTopicId: 301375
dashedName: access-props-using-this-props
---
# --description--
Le ultime sfide hanno mostrato i modi fondamentali per passare le proprietà ai componenti figli. Ma cosa succede se il componente figlio a cui stai passando una prop è un componente di classe ES6, piuttosto che un componente funzionale senza stato? Il componente di classe ES6 utilizza una convenzione leggermente diversa per accedere alle proprietà.
Ogni volta che fai riferimento a un componente di classe all'interno di sé stesso, usa la parola chiave `this`. Per accedere alle proprietà all'interno di un componente di classe, premetti `this` al codice che usi per accedervi. Ad esempio, se un componente di classe ES6 ha una prop chiamata `data`, scriverai `{this.props.data}` in JSX.
# --instructions--
Mostra un'istanza del componente `ReturnTempPassword` nel componente genitore `ResetPassword`. Qui, dai a `ReturnTempPassword` una prop di `tempPassword` e assegnale un valore stringa di almeno 8 caratteri. All'interno del figlio, `ReturnTempPassword`, accedi alla prop `tempPassword` all'interno dei tag `strong` per assicurarti che l'utente veda la password temporanea.
# --hints--
Il componente `ResetPassword` dovrebbe restituire un singolo elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ResetPassword));
return mockedComponent.children().type() === 'div';
})()
);
```
Il quarto figlio di `ResetPassword` dovrebbe essere il componente `ReturnTempPassword`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ResetPassword));
return (
mockedComponent.children().childAt(3).name() === 'ReturnTempPassword'
);
})()
);
```
Il componente `ReturnTempPassword` dovrebbe avere una prop chiamata `tempPassword`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ResetPassword));
return mockedComponent.find('ReturnTempPassword').props().tempPassword;
})()
);
```
L'elemento `tempPassword` di `ReturnTempPassword` dovrebbe essere uguale a una stringa di almeno 8 caratteri.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ResetPassword));
const temp = mockedComponent.find('ReturnTempPassword').props()
.tempPassword;
return typeof temp === 'string' && temp.length >= 8;
})()
);
```
Il componente `ReturnTempPassword` dovrebbe visualizzare la password che crei come prop `tempPassword` all'interno dei tag `strong`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ResetPassword));
return (
mockedComponent.find('strong').text() ===
mockedComponent.find('ReturnTempPassword').props().tempPassword
);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<ResetPassword />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class ReturnTempPassword extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
{ /* Change code below this line */ }
<p>Your temporary password is: <strong></strong></p>
{ /* Change code above this line */ }
</div>
);
}
};
class ResetPassword extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Reset Password</h2>
<h3>We've generated a new temporary password for you.</h3>
<h3>Please reset this password from your account settings ASAP.</h3>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
```
# --solutions--
```jsx
class ReturnTempPassword extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<p>Your temporary password is: <strong>{this.props.tempPassword}</strong></p>
</div>
);
}
};
class ResetPassword extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Reset Password</h2>
<h3>We've generated a new temporary password for you.</h3>
<h3>Please reset this password from your account settings ASAP.</h3>
{ /* Change code below this line */ }
<ReturnTempPassword tempPassword="serrPbqrPnzc" />
{ /* Change code above this line */ }
</div>
);
}
};
```

View File

@ -0,0 +1,82 @@
---
id: 5a24bbe0dba28a8d3cbd4c5e
title: Aggiungere commenti in JSX
challengeType: 6
forumTopicId: 301376
dashedName: add-comments-in-jsx
---
# --description--
JSX è una sintassi che viene compilata in JavaScript valido. A volte, per la leggibilità, potresti aver bisogno di aggiungere commenti al tuo codice. Come la maggior parte dei linguaggi di programmazione, JSX ha il proprio modo di farlo.
Per inserire i commenti all'interno di JSX, si utilizza la sintassi `{/* */}` per racchiudere il testo del commento.
# --instructions--
L'editor di codice contiene un elemento JSX simile a quello creato nell'ultima sfida. Aggiungi un commento da qualche parte all'interno dell'elemento `div` fornito, senza modificare gli elementi `h1` o `p`.
# --hints--
La costante `JSX` dovrebbe restituire un elemento `div`.
```js
assert(JSX.type === 'div');
```
Il `div` dovrebbe contenere un tag `h1` come primo elemento.
```js
assert(JSX.props.children[0].type === 'h1');
```
Il `div` dovrebbe contenere un tag `p` come secondo elemento.
```js
assert(JSX.props.children[1].type === 'p');
```
Gli elementi `h1` e `p` esistenti non dovrebbero essere modificati.
```js
assert(
JSX.props.children[0].props.children === 'This is a block of JSX' &&
JSX.props.children[1].props.children === "Here's a subtitle"
);
```
Il `JSX` dovrebbe usare la sintassi valida per i commenti.
```js
assert(/<div>[\s\S]*{\s*\/\*[\s\S]*\*\/\s*}[\s\S]*<\/div>/.test(code));
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(JSX, document.getElementById('root'))
```
## --seed-contents--
```jsx
const JSX = (
<div>
<h1>This is a block of JSX</h1>
<p>Here's a subtitle</p>
</div>
);
```
# --solutions--
```jsx
const JSX = (
<div>
<h1>This is a block of JSX</h1>
{ /* this is a JSX comment */ }
<p>Here's a subtitle</p>
</div>);
```

View File

@ -0,0 +1,179 @@
---
id: 5a24c314108439a4d403617e
title: Aggiungere listener di eventi
challengeType: 6
forumTopicId: 301377
dashedName: add-event-listeners
---
# --description--
Il metodo `componentDidMount()` è anche il posto migliore per allegare i listener di eventi di cui hai bisogno per aggiungere funzionalità specifiche. React fornisce un sistema di eventi sintetico che avvolge il sistema nativo di eventi presente nei browser. Questo significa che il sistema di eventi sintetico si comporta esattamente allo stesso modo indipendentemente dal browser dell'utente - anche se gli eventi nativi possono comportarsi in modo diverso tra i diversi browser.
Hai già utilizzato alcuni di questi gestori di eventi sintetici come `onClick()`. Il sistema di eventi sintetici di React è ottimo da utilizzare per la maggior parte delle interazioni che gestirai su elementi del DOM. Tuttavia, se desideri collegare un gestore di eventi agli oggetti document o window, è necessario farlo direttamente.
# --instructions--
Collega un listener (ascoltatore) di eventi nel metodo `componentDidMount()` per gli eventi `keydown` e fai sì che questi eventi attivino la callback `handleKeyPress()`. È possibile utilizzare `document.addEventListener()` che riceve l'evento (tra virgolette) come primo argomento e la callback come secondo argomento.
Poi, in `componentWillUnmount()`, rimuovi questo stesso listener di eventi. Puoi passare gli stessi argomenti a `document.removeEventListener()`. È buona pratica utilizzare questo metodo del ciclo di vita per fare qualsiasi pulizia di componenti React prima che siano smontati e distrutti. Rimuovere i listener di eventi è un esempio di questa azione di pulizia.
# --hints--
`MyComponent` dovrebbe mostrare un elemento `div` che contiene un tag `h1`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.find('div').children().find('h1').length === 1;
})()
);
```
Un listener `keydown` dovrebbe essere collegato al documento in `componentDidMount`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const didMountString = mockedComponent
.instance()
.componentDidMount.toString();
return new RegExp(
'document.addEventListener(.|\n|\r)+keydown(.|\n|\r)+this.handleKeyPress'
).test(didMountString);
})()
);
```
Il listener `keydown` dovrebbe essere rimosso dal documento in `componentWillUnmount`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const willUnmountString = mockedComponent
.instance()
.componentWillUnmount.toString();
return new RegExp(
'document.removeEventListener(.|\n|\r)+keydown(.|\n|\r)+this.handleKeyPress'
).test(willUnmountString);
})()
);
```
Una volta che il componente è montato, premendo `enter` si dovrebbe aggiornare il suo stato e il tag `h1` visualizzato.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const beforeState = mockedComponent.state('message');
const beforeText = mockedComponent.find('h1').text();
const pressEnterKey = () => {
mockedComponent.instance().handleKeyPress({ keyCode: 13 });
return waitForIt(() => {
mockedComponent.update();
return {
state: mockedComponent.state('message'),
text: mockedComponent.find('h1').text()
};
});
};
const afterKeyPress = await pressEnterKey();
assert(
beforeState !== afterKeyPress.state && beforeText !== afterKeyPress.text
);
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
message: ''
};
this.handleEnter = this.handleEnter.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
}
// Change code below this line
componentDidMount() {
}
componentWillUnmount() {
}
// Change code above this line
handleEnter() {
this.setState((state) => ({
message: state.message + 'You pressed the enter key! '
}));
}
handleKeyPress(event) {
if (event.keyCode === 13) {
this.handleEnter();
}
}
render() {
return (
<div>
<h1>{this.state.message}</h1>
</div>
);
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
message: ''
};
this.handleKeyPress = this.handleKeyPress.bind(this);
this.handleEnter = this.handleEnter.bind(this); }
componentDidMount() {
// Change code below this line
document.addEventListener('keydown', this.handleKeyPress);
// Change code above this line
}
componentWillUnmount() {
// Change code below this line
document.removeEventListener('keydown', this.handleKeyPress);
// Change code above this line
}
handleEnter() {
this.setState((state) => ({
message: state.message + 'You pressed the enter key! '
}));
}
handleKeyPress(event) {
if (event.keyCode === 13) {
this.handleEnter();
}
}
render() {
return (
<div>
<h1>{this.state.message}</h1>
</div>
);
}
};
```

View File

@ -0,0 +1,112 @@
---
id: 5a24c314108439a4d4036182
title: Aggiungere stili in linea in React
challengeType: 6
forumTopicId: 301378
dashedName: add-inline-styles-in-react
---
# --description--
Nell'ultima sfida potresti aver notato che ci sono state diverse altre differenze di sintassi dagli stili HTML inline in aggiunta all'attributo `style` impostato su un oggetto JavaScript. In primo luogo, i nomi di alcune proprietà di stile CSS usano il camel case. Ad esempio, l'ultima sfida imposta la dimensione del carattere con `fontSize` invece di `font-size`. Le parole tratteggiate come `font-size` sono una sintassi non valida per le proprietà dell'oggetto JavaScript, quindi React usa il camel case. Di regola, tutte le proprietà di stile tratteggiate sono scritte utilizzando il camel case in JSX.
Si assume che tutti i valori di lunghezza delle proprietà (come `height`, `width`, e `fontSize`) siano in `px` se non diversamente specificato. Se si desidera utilizzare `em`, ad esempio, dovrai inserire il valore e l'unità di misura tra virgolette, come ad esempio `{fontSize: "4em"}`. Oltre ai valori di lunghezza che hanno un'unità predefinita in `px`, tutti gli altri valori delle proprietà dovrebbero essere inseriti tra virgolette.
# --instructions--
Se hai molti stili, puoi assegnare un `object` style a una costante per mantenere il codice ordinato. Dichiara la tua costante di stile come variabile globale nella parte superiore del file. Inizializza la costante `styles` e assegna un `object` con tre proprietà di stile e i relativi valori ad essa. Dai al `div` un colore `purple`, un font-size di `40`, e un bordo di `2px solid purple`. Quindi imposta l'attributo `style` sulla costante `styles`.
# --hints--
La variabile `styles` dovrebbe essere un `object` con tre proprietà.
```js
assert(Object.keys(styles).length === 3);
```
La variabile `styles` dovrebbe avere una proprietà `color` impostata su un valore `purple`.
```js
assert(styles.color === 'purple');
```
La variabile `styles` dovrebbe avere una proprietà `fontSize` impostata su un valore di `40`.
```js
assert(styles.fontSize === 40);
```
La variabile `styles` dovrebbe avere una proprietà `border` impostata su un valore di `2px solid purple`.
```js
assert(styles.border === '2px solid purple');
```
Il componente dovrebbe presentare un elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.shallow(React.createElement(Colorful));
return mockedComponent.type() === 'div';
})()
);
```
L'elemento `div` dovrebbe avere i suoi stili definiti dall'oggetto `styles`.
```js
assert(
(function () {
const mockedComponent = Enzyme.shallow(React.createElement(Colorful));
return (
mockedComponent.props().style.color === 'purple' &&
mockedComponent.props().style.fontSize === 40 &&
mockedComponent.props().style.border === '2px solid purple'
);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<Colorful />, document.getElementById('root'))
```
## --seed-contents--
```jsx
// Change code above this line
class Colorful extends React.Component {
render() {
// Change code below this line
return (
<div style={{color: "yellow", fontSize: 24}}>Style Me!</div>
);
// Change code above this line
}
};
```
# --solutions--
```jsx
const styles = {
color: "purple",
fontSize: 40,
border: "2px solid purple"
};
// Change code above this line
class Colorful extends React.Component {
render() {
// Change code below this line
return (
<div style={styles}>Style Me!</div>
);
// Change code above this line
}
};
```

View File

@ -0,0 +1,136 @@
---
id: 5a24c314108439a4d4036174
title: Associare 'this' a un metodo di classe
challengeType: 6
forumTopicId: 301379
dashedName: bind-this-to-a-class-method
---
# --description--
Oltre a impostare e aggiornare lo `state`, puoi anche definire i metodi per la tua classe componente. Un metodo di classe in genere deve usare la parola chiave `this` in modo da poter accedere alle proprietà della classe (come `state` e `props`) all'interno dell'ambito del metodo. Ci sono alcuni modi per consentire ai tuoi metodi di classe di accedere a `this`.
Un modo comune è quello di associare esplicitamente `this` nel costruttore così `this` viene associato ai metodi della classe quando il componente è inizializzato. Potresti aver notato che l'ultima sfida usava `this.handleClick = this.handleClick.bind(this)` per il suo metodo `handleClick` nel costruttore. Quindi, quando chiamerai una funzione come `this.setState()` all'interno del metodo di classe, `this` si riferirà alla classe e non sarà `undefined`.
**Nota:** La parola chiave `this` è uno degli aspetti di JavaScript che confondono di più, ma svolge un ruolo importante in React. Anche se il suo comportamento qui è del tutto normale, queste lezioni non sono il luogo per un esame approfondito di `this` quindi ti consigliamo di fare riferimento ad altre lezioni se quanto visto sopra non ti è chiaro.
# --instructions--
L'editor di codice ha un componente con uno `state` che tiene traccia del testo. Ha anche un metodo che ti permette di impostare il testo su `You clicked!`. Tuttavia, il metodo non funziona perché usa la parola chiave `this` che è indefinita (undefined). Correggi il problema associando esplicitamente `this` al metodo `handleClick()` nel costruttore del componente.
Successivamente, aggiungi un gestore di click all'elemento `button` nel metodo render. Esso dovrebbe attivare il metodo `handleClick()` quando il bottone riceve un evento click. Ricorda che il metodo che passi al gestore `onClick` necessita di parentesi graffe perché dovrebbe essere interpretato direttamente come JavaScript.
Una volta completati i passaggi di cui sopra, dovresti essere in grado di fare clic sul bottone e vedere `You clicked!`.
# --hints--
`MyComponent` dovrebbe restituire un elemento `div` che avvolge due elementi: nell'ordine un bottone e un `h1`.
```js
assert(
Enzyme.mount(React.createElement(MyComponent)).find('div').length === 1 &&
Enzyme.mount(React.createElement(MyComponent))
.find('div')
.childAt(0)
.type() === 'button' &&
Enzyme.mount(React.createElement(MyComponent))
.find('div')
.childAt(1)
.type() === 'h1'
);
```
Lo stato di `MyComponent` dovrebbe essere inizializzato con la coppia chiave/valore `{ text: "Hello" }`.
```js
assert(
Enzyme.mount(React.createElement(MyComponent)).state('text') === 'Hello'
);
```
Cliccando sull'elemento `button` dovrebbe essere eseguito il metodo `handleClick` e dovrebbe essere impostare lo stato `text` a `You clicked!`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const first = () => {
mockedComponent.setState({ text: 'Hello' });
return waitForIt(() => mockedComponent.state('text'));
};
const second = () => {
mockedComponent.find('button').simulate('click');
return waitForIt(() => mockedComponent.state('text'));
};
const firstValue = await first();
const secondValue = await second();
assert(firstValue === 'Hello' && secondValue === 'You clicked!');
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "Hello"
};
// Change code below this line
// Change code above this line
}
handleClick() {
this.setState({
text: "You clicked!"
});
}
render() {
return (
<div>
{ /* Change code below this line */ }
<button>Click Me</button>
{ /* Change code above this line */ }
<h1>{this.state.text}</h1>
</div>
);
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "Hello"
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
text: "You clicked!"
});
}
render() {
return (
<div>
<button onClick = {this.handleClick}>Click Me</button>
<h1>{this.state.text}</h1>
</div>
);
}
};
```

View File

@ -0,0 +1,176 @@
---
id: 5a24c314108439a4d4036189
title: Cambiare CSS inline condizionalmente in base allo stato dei componenti
challengeType: 6
forumTopicId: 301380
dashedName: change-inline-css-conditionally-based-on-component-state
---
# --description--
A questo punto, hai visto diverse applicazioni del rendering condizionale e l'uso degli stili in linea. Ecco un altro esempio che combina entrambi questi argomenti. Puoi anche fare un render condizionale del CSS in base allo stato di un componente React. Per fare questo si valutare una condizione, e se tale condizione è soddisfatta si modifica l'oggetto styles assegnato agli elementi JSX nel metodo di render.
Questo è un paradigma importante da capire, perché è un grande cambiamento rispetto all'approccio più tradizionale di applicare gli stili modificando direttamente gli elementi del DOM (cosa molto comune con jQuery, per esempio). In quell'approccio, è necessario tenere traccia di quando gli elementi cambiano e anche gestire direttamente la manipolazione effettiva. Può diventare difficile tenere traccia dei cambiamenti, rendendo potenzialmente imprevedibile la tua interfaccia utente. Quando imposti un oggetto di stile in base a una condizione, descrivi l'aspetto dell'interfaccia utente come una funzione dello stato dell'applicazione. Vi è un chiaro flusso di informazioni che si muove in una sola direzione. Questo è il metodo preferito quando si scrivono applicazioni con React.
# --instructions--
L'editor di codice contiene un semplice componente di input controllato con un bordo stilizzato. Vogliamo rendere questo bordo rosso se l'utente digita più di 15 caratteri di testo nella casella di input. Aggiungi una condizione per controllare questo e, se la condizione è valida, imposta lo stile del bordo della casella di input a `3px solid red`. Puoi provarlo inserendo il testo nell'input.
# --hints--
Il componente `GateKeeper` dovrebbe presentare un elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
return mockedComponent.find('div').length === 1;
})()
);
```
Il componente `GateKeeper` dovrebbe essere inizializzato con una chiave di stato `input` impostata su una stringa vuota.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
return mockedComponent.state().input === '';
})()
);
```
Il componente `GateKeeper` dovrebbe presentare un tag `h3` e un tag `input`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
return (
mockedComponent.find('h3').length === 1 &&
mockedComponent.find('input').length === 1
);
})()
);
```
Il tag `input` inizialmente dovrebbe avere uno stile di `1px solid black` per la proprietà `border`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
return (
mockedComponent.find('input').props().style.border === '1px solid black'
);
})()
);
```
Il tag `input` dovrebbe essere stilizzato con un bordo di `3px solid red` se il valore di input nello stato è più lungo di 15 caratteri.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 100));
const mockedComponent = Enzyme.mount(React.createElement(GateKeeper));
const simulateChange = (el, value) =>
el.simulate('change', { target: { value } });
let initialStyle = mockedComponent.find('input').props().style.border;
const state_1 = () => {
mockedComponent.setState({ input: 'this is 15 char' });
return waitForIt(() => mockedComponent.find('input').props().style.border);
};
const state_2 = () => {
mockedComponent.setState({
input: 'A very long string longer than 15 characters.'
});
return waitForIt(() => mockedComponent.find('input').props().style.border);
};
const style_1 = await state_1();
const style_2 = await state_2();
assert(
initialStyle === '1px solid black' &&
style_1 === '1px solid black' &&
style_2 === '3px solid red'
);
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<GateKeeper />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Change code below this line
// Change code above this line
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
```
# --solutions--
```jsx
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
if (this.state.input.length > 15) {
inputStyle.border = '3px solid red';
};
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
```

View File

@ -0,0 +1,199 @@
---
id: 5a24c314108439a4d4036166
title: Creare componenti React
challengeType: 6
forumTopicId: 301381
dashedName: compose-react-components
---
# --description--
Dato che le sfide continuano a utilizzare composizioni più complesse di componenti React e JSX, c'è un punto importante da osservare. Il rendering di componenti di classe stile ES6 all'interno di altri componenti non è diverso dal render dei componenti semplici che hai usato nelle ultime sfide. All'interno di altri componenti puoi fare il render di elementi JSX, componenti funzionali senza stato, e componenti di classe ES6.
# --instructions--
Nell'editor di codice, il componente `TypesOfFood` sta già mostrando un componente chiamato `Vegetables`. Inoltre, c'è il componente `Fruits` preso dall'ultima sfida.
Annida due componenti all'interno di `Fruits` — prima `NonCitrus`, e poi `Citrus`. Entrambi questi componenti ti sono forniti dietro le quinte. Successivamente, annida il componente di classe `Fruits` nel componente `TypesOfFood`, sotto l'intestazione `h1` e sopra `Vegetables`. Il risultato dovrebbe essere una serie di componenti annidati, che utilizza due tipi di componenti diversi.
# --hints--
Il componente `TypesOfFood` dovrebbe restituire un singolo elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(TypesOfFood));
return mockedComponent.children().type() === 'div';
})()
);
```
Il componente `TypesOfFood` dovrebbe restituire il componente `Fruits`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(TypesOfFood));
return mockedComponent.children().childAt(1).name() === 'Fruits';
})()
);
```
Il componente `Fruits` dovrebbe restituire il componente `NonCitrus` e il componente `Citrus`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(TypesOfFood));
return (
mockedComponent.find('Fruits').children().find('NonCitrus').length ===
1 &&
mockedComponent.find('Fruits').children().find('Citrus').length === 1
);
})()
);
```
Il componente `TypesOfFood` dovrebbe restituire il componente `Vegetables` sotto il componente `Fruits`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(TypesOfFood));
return mockedComponent.children().childAt(2).name() === 'Vegetables';
})()
);
```
# --seed--
## --before-user-code--
```jsx
class NonCitrus extends React.Component {
render() {
return (
<div>
<h4>Non-Citrus:</h4>
<ul>
<li>Apples</li>
<li>Blueberries</li>
<li>Strawberries</li>
<li>Bananas</li>
</ul>
</div>
);
}
};
class Citrus extends React.Component {
render() {
return (
<div>
<h4>Citrus:</h4>
<ul>
<li>Lemon</li>
<li>Lime</li>
<li>Orange</li>
<li>Grapefruit</li>
</ul>
</div>
);
}
};
class Vegetables extends React.Component {
render() {
return (
<div>
<h2>Vegetables:</h2>
<ul>
<li>Brussel Sprouts</li>
<li>Broccoli</li>
<li>Squash</li>
</ul>
</div>
);
}
};
```
## --after-user-code--
```jsx
ReactDOM.render(<TypesOfFood />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class Fruits extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Fruits:</h2>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
class TypesOfFood extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>Types of Food:</h1>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
<Vegetables />
</div>
);
}
};
```
# --solutions--
```jsx
class Fruits extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Fruits:</h2>
{ /* Change code below this line */ }
<NonCitrus />
<Citrus />
{ /* Change code above this line */ }
</div>
)
}
}
class TypesOfFood extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>Types of Food:</h1>
{ /* Change code below this line */ }
<Fruits />
{ /* Change code above this line */ }
<Vegetables />
</div>
);
}
};
```

View File

@ -0,0 +1,110 @@
---
id: 5a24bbe0dba28a8d3cbd4c5d
title: Creare un elemento JSX complesso
challengeType: 6
forumTopicId: 301382
dashedName: create-a-complex-jsx-element
---
# --description--
L'ultima sfida è stata un semplice esempio di JSX, ma JSX può rappresentare anche HTML più complesso.
Una cosa importante da sapere sul JSX annidato è che deve restituire un singolo elemento.
Questo elemento genitore avvolgerà tutti gli altri livelli di elementi annidati.
Per esempio, diversi elementi JSX scritti come fratelli senza un elemento genitore che li contenga, non saranno transcodificati.
Ecco un esempio:
**JSX valido:**
```jsx
<div>
<p>Paragraph One</p>
<p>Paragraph Two</p>
<p>Paragraph Three</p>
</div>
```
**JSX non valido:**
```jsx
<p>Paragraph One</p>
<p>Paragraph Two</p>
<p>Paragraph Three</p>
```
# --instructions--
Definisci una nuova costante `JSX` che esegua il render di un `div` che contenga i seguenti elementi in ordine:
Un `h1`, un `p`e una lista non ordinata che contiene tre elementi `li`. Puoi includere qualsiasi testo desideri all'interno di ogni elemento.
**Nota:** Quando si visualizzano più elementi come questo, è possibile avvolgerli tutti in parentesi, ma non è strettamente necessario. Nota anche che questa sfida utilizza un tag `div` per avvolgere tutti gli elementi figli all'interno di un singolo elemento genitore. Se rimuovi il `div`, il JSX non sarà più transcodificato. Tienilo a mente, perché questo si applicherà anche quando restituirai elementi JSX in componenti React.
# --hints--
La costante `JSX` dovrebbe restituire un elemento `div`.
```js
assert(JSX.type === 'div');
```
Il `div` dovrebbe contenere un tag `h1` come primo elemento.
```js
assert(JSX.props.children[0].type === 'h1');
```
Il `div` dovrebbe contenere un tag `p` come secondo elemento.
```js
assert(JSX.props.children[1].type === 'p');
```
Il `div` dovrebbe contenere un tag `ul` come terzo elemento.
```js
assert(JSX.props.children[2].type === 'ul');
```
L'elemento `ul` dovrebbe contenere tre elementi `li`.
```js
assert(
JSX.props.children
.filter((ele) => ele.type === 'ul')[0]
.props.children.filter((ele) => ele.type === 'li').length === 3
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(JSX, document.getElementById('root'))
```
## --seed-contents--
```jsx
```
# --solutions--
```jsx
const JSX = (
<div>
<h1>Hello JSX!</h1>
<p>Some info</p>
<ul>
<li>An item</li>
<li>Another item</li>
<li>A third item</li>
</ul>
</div>);
```

View File

@ -0,0 +1,134 @@
---
id: 5a24c314108439a4d4036164
title: Creare un componente con una composizione
challengeType: 6
forumTopicId: 301383
dashedName: create-a-component-with-composition
---
# --description--
Ora esamineremo come possiamo mettere insieme più componenti React. Immagina di costruire un'app e di aver creato tre componenti: una `Navbar`, una `Dashboard` e un `Footer`.
Per mettere insieme questi componenti, è possibile creare un componente `App` *genitore* che fa il render di ciascuno di questi tre componenti come *figli*. Per fare il render di un componente come figlio in un componente React, devi includere il nome del componente scritto come tag HTML personalizzato nel file JSX. Ad esempio, nel metodo `render` puoi scrivere:
```jsx
return (
<App>
<Navbar />
<Dashboard />
<Footer />
</App>
)
```
Quando React incontra un tag HTML personalizzato che fa riferimento ad un altro componente (un nome componente inserito in `< />` come in questo esempio), visualizza il markup per quel componente nella posizione del tag. Questo dovrebbe illustrare la relazione genitore/figlio tra il componente `App` e la `Navbar`, la `Dashboard`, e il `Footer`.
# --instructions--
Nell'editor di codice, c'è un semplice componente funzionale chiamato `ChildComponent` e un componente di classe chiamato `ParentComponent`. Componi i due insieme facendo il render del `ChildComponent` all'interno del `ParentComponent`. Assicurati di chiudere il tag `ChildComponent` con una barra in avanti (/).
**Nota:** `ChildComponent` è definito con una funzione freccia ES6 perché questa è una pratica molto comune quando si utilizza React. Tuttavia, sappi che questa è solo una funzione. Se non hai familiarità con la sintassi delle funzioni freccia, fai riferimento alla sezione JavaScript.
# --hints--
Il componente React dovrebbe restituire un singolo elemento `div`.
```js
assert(
(function () {
var shallowRender = Enzyme.shallow(React.createElement(ParentComponent));
return shallowRender.type() === 'div';
})()
);
```
Il componente dovrebbe restituire due elementi annidati.
```js
assert(
(function () {
var shallowRender = Enzyme.shallow(React.createElement(ParentComponent));
return shallowRender.children().length === 2;
})()
);
```
Il componente dovrebbe restituire il componente `ChildComponent` come secondo figlio.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ParentComponent));
return (
mockedComponent.find('ParentComponent').find('ChildComponent').length ===
1
);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<ParentComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const ChildComponent = () => {
return (
<div>
<p>I am the child</p>
</div>
);
};
class ParentComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>I am the parent</h1>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
```
# --solutions--
```jsx
const ChildComponent = () => {
return (
<div>
<p>I am the child</p>
</div>
);
};
class ParentComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>I am the parent</h1>
{ /* Change code below this line */ }
<ChildComponent />
{ /* Change code above this line */ }
</div>
);
}
};
```

View File

@ -0,0 +1,220 @@
---
id: 5a24c314108439a4d4036179
title: Creare un modulo controllato
challengeType: 6
forumTopicId: 301384
dashedName: create-a-controlled-form
---
# --description--
L'ultima sfida ha mostrato che React può controllare lo stato interno di alcuni elementi come `input` e `textarea`, il che li rende componenti controllati. Questo vale anche per altri elementi dei moduli, tra cui il normale elemento HTML `form`.
# --instructions--
Il componente `MyForm` è impostato con un `form` vuoto con un gestore di invio. Il gestore di invio verrà chiamato al momento dell'invio del modulo.
Abbiamo aggiunto un bottone che invia il modulo. Puoi vedere che il `type` è impostato su `submit` indicando che è il bottone che controlla il modulo. Aggiungi l'elemento `input` nel `form` e imposta i suoi attributi `value` e `onChange()` come nell'ultima sfida. Dovresti quindi completare il metodo `handleSubmit` in modo che imposti la proprietà di stato `submit` del componente al valore corrente di input nello `state` locale.
**Nota:** Devi anche chiamare `event.preventDefault()` nel gestore di invio, per evitare il comportamento predefinito di invio del modulo che ricaricherà la pagina web. Per comodità, il comportamento predefinito è stato disabilitato qui per evitare che gli aggiornamenti reimpostino il codice della sfida.
Infine, crea un tag `h1` dopo il `form` che mostri il valore `submit` dallo `state` del componente. Puoi quindi digitare nel modulo e fare clic sul bottone (o premere invio), e dovresti vedere il tuo input presentato nella pagina.
# --hints--
`MyForm` dovrebbe restituire un elemento `div` che contiene un `form` e un tag `h1`. Il modulo dovrebbe includere un `input` e un `button`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyForm));
return (
mockedComponent.find('div').children().find('form').length === 1 &&
mockedComponent.find('div').children().find('h1').length === 1 &&
mockedComponent.find('form').children().find('input').length === 1 &&
mockedComponent.find('form').children().find('button').length === 1
);
})()
);
```
Lo stato di `MyForm` dovrebbe essere inizializzato con le proprietà `input` e `submit`, entrambe impostate su stringhe vuote.
```js
assert(
Enzyme.mount(React.createElement(MyForm)).state('input') === '' &&
Enzyme.mount(React.createElement(MyForm)).state('submit') === ''
);
```
Scrivendo dentro all'elemento `input` si dovrebbe aggiornare la proprietà `input` dello stato del componente.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyForm));
const _1 = () => {
mockedComponent.setState({ input: '' });
return mockedComponent.state('input');
};
const _2 = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: 'TestInput' } });
return {
state: mockedComponent.state('input'),
inputVal: mockedComponent.find('input').props().value
};
};
const before = _1();
const after = _2();
assert(
before === '' &&
after.state === 'TestInput' &&
after.inputVal === 'TestInput'
);
})();
```
L'invio del modulo dovrebbe eseguire `handleSubmit` che dovrebbe impostare la proprietà `submit` nello stato in modo che sia uguale all'input corrente.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyForm));
const _1 = () => {
mockedComponent.setState({ input: '' });
mockedComponent.setState({ submit: '' });
mockedComponent
.find('input')
.simulate('change', { target: { value: 'SubmitInput' } });
return mockedComponent.state('submit');
};
const _2 = () => {
mockedComponent.find('form').simulate('submit');
return mockedComponent.state('submit');
};
const before = _1();
const after = _2();
assert(before === '' && after === 'SubmitInput');
})();
```
`handleSubmit` dovrebbe chiamare `event.preventDefault`
```js
assert(
__helpers.isCalledWithNoArgs(
'event.preventDefault',
MyForm.prototype.handleSubmit.toString()
)
);
```
L'intestazione `h1` dovrebbe fare il render del valore del campo `submit` prendendolo dallo stato del componente.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyForm));
const _1 = () => {
mockedComponent.setState({ input: '' });
mockedComponent.setState({ submit: '' });
mockedComponent
.find('input')
.simulate('change', { target: { value: 'TestInput' } });
return mockedComponent.find('h1').text();
};
const _2 = () => {
mockedComponent.find('form').simulate('submit');
return mockedComponent.find('h1').text();
};
const before = _1();
const after = _2();
assert(before === '' && after === 'TestInput');
})();
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyForm />, document.getElementById('root'));
```
## --seed-contents--
```jsx
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
input: '',
submit: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
input: event.target.value
});
}
handleSubmit(event) {
// Change code below this line
// Change code above this line
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
{/* Change code below this line */}
{/* Change code above this line */}
<button type='submit'>Submit!</button>
</form>
{/* Change code below this line */}
{/* Change code above this line */}
</div>
);
}
}
```
# --solutions--
```jsx
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {
input: '',
submit: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
input: event.target.value
});
}
handleSubmit(event) {
event.preventDefault();
this.setState(state => ({
submit: state.input
}));
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input value={this.state.input} onChange={this.handleChange} />
<button type='submit'>Submit!</button>
</form>
<h1>{this.state.submit}</h1>
</div>
);
}
}
```

View File

@ -0,0 +1,150 @@
---
id: 5a24c314108439a4d4036178
title: Creare un input controllato
challengeType: 6
forumTopicId: 301385
dashedName: create-a-controlled-input
---
# --description--
La tua applicazione potrebbe avere interazioni più complesse tra lo `state` e l'interfaccia utente presentata. Ad esempio, i controlli dei moduli per l'input di testo, come `input` e `textarea`, mangengono il proprio stato nel DOM mentre l'utente digita. Con React, puoi spostare questo stato mutabile nello `state` di un componente React. L'input dell'utente diventa parte dello `state` dell'applicazione, quindi React controlla il valore di quel campo di input. In genere, se hai componenti React con campi di input in cui l'utente può digitare, avrai un modulo con input controllato.
# --instructions--
L'editor di codice ha lo scheletro di un componente chiamato `ControlledInput` per creare un elemento `input` controllato. Lo `state` del componente è già inizializzato con una proprietà `input` che contiene una stringa vuota. Questo valore rappresenta il testo che un utente digita nel campo `input`.
Innanzitutto, crea un metodo chiamato `handleChange()` che abbia un parametro denominato `event`. Quando il metodo viene chiamato, riceve un oggetto `event` che contiene una stringa di testo presa dall'elemento `input`. Puoi accedere a questa stringa con `event.target.value` all'interno del metodo. Aggiorna la proprietà `input` dello `state` del componente con questa nuova stringa.
Nel metodo `render`, crea l'elemento `input` sopra il tag `h4`. Aggiungi un attributo `value` uguale alla proprietà `input` dello `state` del componente. Quindi aggiungi un gestore di evento `onChange()` impostato al metodo `handleChange()`.
Quando scrivi nella casella di input, quel testo viene elaborato dal metodo `handleChange()`, impostato come proprietà `input` nello `state` locale, e presentato come valore nella casella di `input` della pagina. Il componente `state` è la singola fonte autorevole per quanto riguarda i dati di input.
Ultimo ma non meno importante, non dimenticate di aggiungere i binding necessari nel costruttore.
# --hints--
`ControlledInput` dovrebbe restituire un elemento `div` che contiene un `input` e un tag `p`.
```js
assert(
Enzyme.mount(React.createElement(ControlledInput))
.find('div')
.children()
.find('input').length === 1 &&
Enzyme.mount(React.createElement(ControlledInput))
.find('div')
.children()
.find('p').length === 1
);
```
Lo stato di `ControlledInput` dovrebbe essere inizializzato con una proprietà `input` impostata su una stringa vuota.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(ControlledInput)).state('input'),
''
);
```
La digitazione nell'elemento di input dovrebbe aggiornare lo stato e il valore dell'input, e l'elemento `p` dovrebbe mostrare questo stato mentre scrivi.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(ControlledInput));
const _1 = () => {
mockedComponent.setState({ input: '' });
return waitForIt(() => mockedComponent.state('input'));
};
const _2 = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: 'TestInput' } });
return waitForIt(() => ({
state: mockedComponent.state('input'),
text: mockedComponent.find('p').text(),
inputVal: mockedComponent.find('input').props().value
}));
};
const before = await _1();
const after = await _2();
assert(
before === '' &&
after.state === 'TestInput' &&
after.text === 'TestInput' &&
after.inputVal === 'TestInput'
);
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<ControlledInput />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
// Change code below this line
// Change code above this line
}
// Change code below this line
// Change code above this line
render() {
return (
<div>
{ /* Change code below this line */}
{ /* Change code above this line */}
<h4>Controlled Input:</h4>
<p>{this.state.input}</p>
</div>
);
}
};
```
# --solutions--
```jsx
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
input: event.target.value
});
}
render() {
return (
<div>
<input
value={this.state.input}
onChange={this.handleChange} />
<h4>Controlled Input:</h4>
<p>{this.state.input}</p>
</div>
);
}
};
```

View File

@ -0,0 +1,102 @@
---
id: 5a24c314108439a4d4036163
title: Creare un componente React
challengeType: 6
forumTopicId: 301386
dashedName: create-a-react-component
---
# --description--
L'altro modo per definire un componente React è con la sintassi ES6 `class`. Nell'esempio seguente, `Kitten` estende `React.Component`:
```jsx
class Kitten extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<h1>Hi</h1>
);
}
}
```
Questo crea una classe ES6 `Kitten` che estende la classe `React.Component`. Così la classe `Kitten` ora ha accesso a molte funzionalità React utili, come lo stato locale (local state) e gli agganci del ciclo di vita (lifecycle hook). Non preoccuparti se non hai ancora familiarità con questi termini, saranno coperti in maggior dettaglio nelle sfide successive. Nota anche che la classe `Kitten` ha un `constructor` definito al suo interno che chiama `super()`. Esso usa `super()` per chiamare il costruttore della classe genitore, in questo caso `React.Component`. Il costruttore è un metodo speciale usato durante l'inizializzazione degli oggetti creati con la parola chiave `class`. È buona pratica chiamare il `constructor` di un componente con `super` e passare le `props` ad entrambi. Questo assicura che il componente sia inizializzato correttamente. Per adesso, sappi che è uno standard includere questo codice. Presto vedrai altri usi per il costruttore e le `props`.
# --instructions--
`MyComponent` è definito nell'editor di codice usando la sintassi di classe. Termina la scrittura del metodo `render` in modo che restituisca un elemento `div` che contiene un `h1` con il testo `Hello React!`.
# --hints--
Il componente React dovrebbe restituire un elemento `div`.
```js
assert(Enzyme.shallow(React.createElement(MyComponent)).type() === 'div');
```
Il `div` restituito dovrebbe fare il render di un header `h1` al suo interno.
```js
assert(
/<div><h1>.*<\/h1><\/div>/.test(
Enzyme.shallow(React.createElement(MyComponent)).html()
)
);
```
L'intestazione `h1` dovrebbe contenere la stringa `Hello React!`.
```js
assert(
Enzyme.shallow(React.createElement(MyComponent)).html() ===
'<div><h1>Hello React!</h1></div>'
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
// Change code below this line
// Change code above this line
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
// Change code below this line
return (
<div>
<h1>Hello React!</h1>
</div>
);
// Change code above this line
}
};
```

View File

@ -0,0 +1,57 @@
---
id: 587d7dbc367417b2b2512bb1
title: Creare un semplice elemento JSX
challengeType: 6
forumTopicId: 301390
dashedName: create-a-simple-jsx-element
---
# --description--
React è una libreria di visualizzazione Open Source creata e mantenuta da Facebook. È un ottimo strumento per presentare l'interfaccia utente (UI) delle moderne applicazioni web.
React utilizza un'estensione della sintassi di JavaScript chiamata JSX che consente di scrivere HTML direttamente all'interno di JavaScript. Questo ha diversi vantaggi. Ti permette di utilizzare la potenza programmatica completa di JavaScript all'interno di HTML, e aiuta a mantenere il codice leggibile. Per la maggior parte, JSX è simile all'HTML che hai già imparato, tuttavia vi sono alcune differenze fondamentali che saranno affrontate nel corso di queste sfide.
Ad esempio, poiché JSX è un'estensione sintattica di JavaScript, è possibile scrivere JavaScript direttamente all'interno di JSX. Per fare questo, è sufficiente includere il codice che si desidera trattare come JavaScript all'interno di parentesi graffe: `{ 'questo è trattato come codice JavaScript' }`. Tienilo a mente, dato che sarà utilizzato in diverse sfide future.
Tuttavia, poiché JSX non è JavaScript valido, il codice JSX deve essere compilato in JavaScript. Il transpiler Babel è uno strumento popolare per questo processo. Per tua convenienza, è già aggiunto dietro le quinte per queste sfide. Se ti capita di scrivere JSX sintatticamente non valido, vedrai il primo test in queste sfide fallire.
Vale la pena notare che sotto il cofano le sfide chiamano `ReactDOM.render(JSX, document.getElementById('root'))`. Questa chiamata di funzione è ciò che posiziona il tuo JSX nella rappresentazione leggera del DOM propria di React. React usa delle istantanee del proprio DOM per ottimizzare l'aggiornamento di parti specifiche del DOM.
# --instructions--
Il codice corrente utilizza JSX per assegnare un elemento `div` alla costante `JSX`. Sostituisci il `div` con un elemento `h1` e aggiungi il testo `Hello JSX!` al suo interno.
# --hints--
La costante `JSX` dovrebbe restituire un elemento `h1`.
```js
assert(JSX.type === 'h1');
```
Il tag `h1` dovrebbe includere il testo `Hello JSX!`
```js
assert(Enzyme.shallow(JSX).contains('Hello JSX!'));
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(JSX, document.getElementById('root'))
```
## --seed-contents--
```jsx
const JSX = <div></div>;
```
# --solutions--
```jsx
const JSX = <h1>Hello JSX!</h1>;
```

View File

@ -0,0 +1,134 @@
---
id: 5a24c314108439a4d4036170
title: Creare un componente con state
challengeType: 6
forumTopicId: 301391
dashedName: create-a-stateful-component
---
# --description--
Uno degli argomenti più importanti in React è lo stato (`state`). Lo stato è costituito da tutti i dati che la tua applicazione ha bisogno di conoscere, che possono cambiare nel tempo. Vuoi che le tue app rispondano alle modifiche di stato e presentino un'interfaccia utente aggiornata quando necessario. React offre una bella soluzione per la gestione dello stato di applicazioni web moderne.
Puoi creare lo stato in un componente React dichiarando una proprietà `state` nel `constructor` della classe del componente. Questo inizializza il componente con lo `state` quando viene creato. La proprietà `state` deve essere impostata su un `object` JavaScript. La dichiarazione appare così:
```jsx
this.state = {
}
```
Hai accesso all'oggetto `state` per tutta la vita del tuo componente. Puoi aggiornarlo, farne il rendering (cioè visualizzarlo) nella tua interfaccia utente e passarlo come proprietà ai componenti figli. L'oggetto `state` può essere semplice o complesso in base alle tue necessità. Nota che devi creare un componente di classe estendendo `React.Component` per creare uno `state` di questo tipo.
# --instructions--
C'è un componente nell'editor di codice che sta cercando di fare il render di una proprietà `name` dal suo `state`. Tuttavia non c'è uno `state` definito. Inizializza il componente con `state` nel `constructor` e assegna il tuo nome a una proprietà `name`.
# --hints--
`StatefulComponent` dovrebbe esistere ed effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(
React.createElement(StatefulComponent)
);
return mockedComponent.find('StatefulComponent').length === 1;
})()
);
```
`StatefulComponent` dovrebbe fare il render di un `div` e di un elemento `h1`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(
React.createElement(StatefulComponent)
);
return (
mockedComponent.find('div').length === 1 &&
mockedComponent.find('h1').length === 1
);
})()
);
```
Lo stato di `StatefulComponent` dovrebbe essere inizializzato con una proprietà `name` impostata su una stringa.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(
React.createElement(StatefulComponent)
);
const initialState = mockedComponent.state();
return (
typeof initialState === 'object' && typeof initialState.name === 'string'
);
})()
);
```
La proprietà `name` nello stato di `StatefulComponent` dovrebbe presentare l'elemento `h1`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(
React.createElement(StatefulComponent)
);
const initialState = mockedComponent.state();
return mockedComponent.find('h1').text() === initialState.name;
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<StatefulComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class StatefulComponent extends React.Component {
constructor(props) {
super(props);
// Only change code below this line
// Only change code above this line
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
</div>
);
}
};
```
# --solutions--
```jsx
class StatefulComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'freeCodeCamp!'
}
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
</div>
);
}
};
```

View File

@ -0,0 +1,102 @@
---
id: 5a24c314108439a4d4036162
title: Creare un componente funzionale senza stato
challengeType: 6
forumTopicId: 301392
dashedName: create-a-stateless-functional-component
---
# --description--
I componenti sono il nucleo di React. Tutto in React è un componente e qui imparerai a crearne uno.
Ci sono due modi per creare un componente React. Il primo modo è quello di utilizzare una funzione JavaScript. Definendo un componente in questo modo si crea un *componente funzionale senza stato*. Il concetto di stato in un'applicazione sarà affrontato nelle sfide successive. Per ora, pensa a un componente senza stato (stateless) come a uno che può ricevere i dati e farne il rendering, ma non gestisce o tiene traccia delle modifiche a tali dati. (Copriremo il secondo modo per creare un componente React nella prossima sfida.)
Per creare un componente con una funzione, basta scrivere una funzione JavaScript che restituisce JSX o `null`. Una cosa importante da notare è che React richiede che il nome della funzione inizi con una lettera maiuscola. Ecco un esempio di componente funzionale senza stato che assegna una classe HTML in JSX:
```jsx
const DemoComponent = function() {
return (
<div className='customClass' />
);
};
```
Dopo essere stato transcodificato, il `<div>` avrà una classe CSS di `customClass`.
Poiché un componente JSX rappresenta dell'HTML, è possibile mettere insieme diversi componenti per creare una pagina HTML più complessa. Questo è uno dei vantaggi principali dell'architettura a componente fornita da React. Ti permette di comporre la tua interfaccia utente partendo da molti componenti separati e isolati. Questo rende più facile costruire e mantenere interfacce utente complesse.
# --instructions--
L'editor di codice ha una funzione chiamata `MyComponent`. Completa questa funzione in modo che restituisca un singolo elemento `div` che contiene una stringa di testo.
**Nota:** Il testo è considerato un figlio dell'elemento `div`, quindi non sarai in grado di utilizzare un tag autoconcludente.
# --hints--
`MyComponent` dovrebbe restituire JSX.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.length === 1;
})()
);
```
`MyComponent` dovrebbe restituire un elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.children().type() === 'div';
})()
);
```
L'elemento `div` dovrebbe contenere una stringa di testo.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.find('div').text() !== '';
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const MyComponent = function() {
// Change code below this line
// Change code above this line
}
```
# --solutions--
```jsx
const MyComponent = function() {
// Change code below this line
return (
<div>
Demo Solution
</div>
);
// Change code above this line
}
```

View File

@ -0,0 +1,62 @@
---
id: 5a24c314108439a4d4036160
title: Definire una classe HTML in JSX
challengeType: 6
forumTopicId: 301393
dashedName: define-an-html-class-in-jsx
---
# --description--
Ora che sei a tuo agio con la scrittura in JSX, potresti chiederti come questo differisca dall'HTML.
Finora, può sembrare che HTML e JSX siano esattamente la stessa cosa.
Una differenza chiave in JSX è che non puoi più usare la parola `class` per definire le classi HTML. Questo perché `class` è una parola riservata in JavaScript. JSX utilizza invece `className`.
Infatti, la convenzione di denominazione per tutti gli attributi HTML e riferimenti a eventi in JSX diventa camelCase. Ad esempio, un evento di click in JSX è `onClick`, invece di `onclick`. Allo stesso modo, `onchange` diventa `onChange`. Anche se questa è una differenza sottile, è importante tenerla a mente andando avanti.
# --instructions--
Applica una classe `myDiv` al `div` fornito nel codice JSX.
# --hints--
La costante `JSX` dovrebbe restituire un elemento `div`.
```js
assert.strictEqual(JSX.type, 'div');
```
Il `div` dovrebbe essere di classe `myDiv`.
```js
assert.strictEqual(JSX.props.className, 'myDiv');
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(JSX, document.getElementById('root'))
```
## --seed-contents--
```jsx
const JSX = (
<div>
<h1>Add a class to this div</h1>
</div>
);
```
# --solutions--
```jsx
const JSX = (
<div className = 'myDiv'>
<h1>Add a class to this div</h1>
</div>);
```

View File

@ -0,0 +1,147 @@
---
id: 5a24c314108439a4d403618b
title: Dare agli elementi fratelli un attributo chiave univoco
challengeType: 6
forumTopicId: 301394
dashedName: give-sibling-elements-a-unique-key-attribute
---
# --description--
L'ultima sfida ha mostrato come viene utilizzato il metodo `map` per rendere dinamicamente un certo numero di elementi basati sull'input dell'utente. Tuttavia in quell'esempio mancava una parte importante. Quando crei un array di elementi, ognuno ha bisogno di un attributo `key` impostato su un valore univoco. React utilizza queste chiavi per tenere traccia degli elementi aggiunti, modificati o rimossi. Questo aiuta a rendere il processo di ri-rendering più efficiente quando l'elenco viene modificato in qualsiasi modo.
**Nota:** Le chiavi devono essere uniche solo tra gli elementi fratelli: non c'è bisogno che siano uniche a livello globale nella tua applicazione.
# --instructions--
L'editor di codice ha un array con alcuni framework di front-end e un componente funzionale senza stato chiamato `Frameworks()`. `Frameworks()` ha bisogno di mappare l'array in una lista non ordinata, molto simile a quella dell'ultima sfida. Termina la scrittura della callback di `map` per restituire un elemento `li` per ogni framework nell'array `frontEndFrameworks`. Questa volta, assicurati di dare ad ogni attributo `li` un attributo `key` impostato su un valore univoco. Gli elementi `li` dovrebbero contenere anche del testo preso da `frontEndFrameworks`.
Normalmente, si desidera costruire la chiave con qualcosa che identifica univocamente l'elemento che viene presentato. Come ultima risorsa può essere utilizzato l'indice dell'array, ma in generale dovresti provare a usare un'identificazione univoca.
# --hints--
Il componente `Frameworks` dovrebbe esistere ed essere presentato nella pagina.
```js
assert(
Enzyme.mount(React.createElement(Frameworks)).find('Frameworks').length === 1
);
```
`Frameworks` dovrebbe effetturare il rendering di un elemento `h1`.
```js
assert(Enzyme.mount(React.createElement(Frameworks)).find('h1').length === 1);
```
`Frameworks` dovrebbe effetturare il rendering di un elemento `ul`.
```js
assert(Enzyme.mount(React.createElement(Frameworks)).find('ul').length === 1);
```
Il tag `ul` dovrebbe fare il rendering di 6 elementi figli `li`.
```js
assert(
Enzyme.mount(React.createElement(Frameworks)).find('ul').children().length ===
6 &&
Enzyme.mount(React.createElement(Frameworks))
.find('ul')
.childAt(0)
.name() === 'li' &&
Enzyme.mount(React.createElement(Frameworks)).find('li').length === 6
);
```
Ogni elemento della lista dovrebbe avere un attributo `key` univoco.
```js
assert(
(() => {
const ul = Enzyme.mount(React.createElement(Frameworks)).find('ul');
const keys = new Set([
ul.childAt(0).key(),
ul.childAt(1).key(),
ul.childAt(2).key(),
ul.childAt(3).key(),
ul.childAt(4).key(),
ul.childAt(5).key()
]);
return keys.size === 6;
})()
);
```
Ogni elemento della lista dovrebbe contenere del testo preso da `frontEndFrameworks`.
```js
assert(
(() => {
const li = Enzyme.mount(React.createElement(Frameworks))
.find('ul')
.children();
return [...Array(5)].every((_, i) =>
frontEndFrameworks.includes(li.at(i).text())
);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<Frameworks />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const frontEndFrameworks = [
'React',
'Angular',
'Ember',
'Knockout',
'Backbone',
'Vue'
];
function Frameworks() {
const renderFrameworks = null; // Change this line
return (
<div>
<h1>Popular Front End JavaScript Frameworks</h1>
<ul>
{renderFrameworks}
</ul>
</div>
);
};
```
# --solutions--
```jsx
const frontEndFrameworks = [
'React',
'Angular',
'Ember',
'Knockout',
'Backbone',
'Vue'
];
function Frameworks() {
const renderFrameworks = frontEndFrameworks.map((fw, i) => <li key={i}>{fw}</li>);
return (
<div>
<h1>Popular Front End JavaScript Frameworks</h1>
<ul>
{renderFrameworks}
</ul>
</div>
);
};
```

View File

@ -0,0 +1,104 @@
---
id: 5a24c314108439a4d4036181
title: Gli stili inline
challengeType: 6
forumTopicId: 301395
dashedName: introducing-inline-styles
---
# --description--
Ci sono altri concetti complessi che aggiungono potenti funzionalità al tuo codice React. Ma forse ti stai chiedendo come stilizzare quegli elementi JSX che crei in React. Probabilmente sai che non sarà esattamente come lavorare con HTML a causa del [modo in cui applichi le classi agli elementi JSX](/learn/front-end-development-libraries/react/define-an-html-class-in-jsx).
Se importi degli stili da un foglio di stile, non è poi così diverso. Applichi una classe al tuo elemento JSX usando l'attributo `className` e applichi gli stili alla classe nel tuo foglio di stile. Un'altra opzione è quella di applicare degli stili in linea, che sono molto comuni nello sviluppo di ReactJS.
Puoi applicare degli stili in linea a elementi JSX in modo simile a come faresti in HTML, ma con alcune differenze JSX. Ecco un esempio di uno stile in linea in HTML:
```jsx
<div style="color: yellow; font-size: 16px">Mellow Yellow</div>
```
Gli elementi JSX usano l'attributo `style`, ma a causa del modo in cui JSX è transcodificato, non puoi impostare il valore su una `string`. Invece, gli assegnerai un `object` JavaScript. Ecco un esempio:
```jsx
<div style={{color: "yellow", fontSize: 16}}>Mellow Yellow</div>
```
Vedi come abbiamo usato camelCase nella proprietà `fontSize`? Questo perché React non accetterà le chiavi kebab-case nell'oggetto style. React applicherà per noi il nome di proprietà corretto in HTML.
# --instructions--
Aggiungi un attributo `style` al `div`nell'editor di codice per dare al testo un colore rosso e una dimensione del carattere di `72px`.
Nota che è possibile impostare facoltativamente la dimensione del carattere come un numero, omettendo le unità `px` o scrivendole come `72px`.
# --hints--
Il componente dovrebbe mostrare un elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(Colorful));
return mockedComponent.children().type() === 'div';
})()
);
```
L'elemento `div` dovrebbe avere un colore `red`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(Colorful));
return mockedComponent.children().props().style.color === 'red';
})()
);
```
L'elemento `div` dovrebbe avere una dimensione del carattere di `72px`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(Colorful));
return (
mockedComponent.children().props().style.fontSize === 72 ||
mockedComponent.children().props().style.fontSize === '72' ||
mockedComponent.children().props().style.fontSize === '72px'
);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<Colorful />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class Colorful extends React.Component {
render() {
return (
<div>Big Red</div>
);
}
};
```
# --solutions--
```jsx
class Colorful extends React.Component {
render() {
return (
<div style={{color: "red", fontSize: 72}}>Big Red</div>
);
}
};
```

View File

@ -0,0 +1,75 @@
---
id: 5a24c314108439a4d4036161
title: Tag JSX a chiusura automatica
challengeType: 6
forumTopicId: 301396
dashedName: learn-about-self-closing-jsx-tags
---
# --description--
Finora, hai visto come JSX si differenzia dall'HTML in modo essenziale con l'uso di `className` al posto di `class` per la definizione delle classi HTML.
Un altro aspetto importante in cui JSX differisce da HTML è quello che riguarda i tag a chiusura automatica (self-closing).
In HTML, quasi tutti i tag hanno sia un tag di apertura che di chiusura: `<div></div>`; il tag di chiusura ha sempre una barra in avanti prima del nome del tag che si sta chiudendo. Tuttavia, ci sono dei casi speciali in HTML chiamati “tag a chiusura automatica”, cioè dei tag che non richiedono sia un tag di apertura che di chiusura prima che un altro tag possa iniziare.
Ad esempio, il tag line-break può essere scritto come `<br>` o come `<br />`, ma non dovrebbe mai essere scritto come `<br></br>`, poiché non contiene alcun contenuto.
In JSX, le regole sono un po 'diverse. Qualsiasi elemento JSX può essere scritto con un tag a chiusura automatica, e ogni elemento deve essere chiuso. Il tag line-break, ad esempio, deve essere sempre scritto come `<br />` per essere codice JSX valido che possa essere transcodificato. Un `<div>`, invece, può essere scritto come `<div />` o `<div></div>`. La differenza è che nella prima versione della sintassi non c'è modo di includere nulla nel `<div />`. Vedrai nelle sfide successive che questa sintassi è utile durante il rendering dei componenti React.
# --instructions--
Correggi gli errori nell'editor di codice in modo che sia JSX valido e venga transcodificato con successo. Assicurati di non modificare nessuno dei contenuti - devi solo chiudere i tag dove necessario.
# --hints--
La costante `JSX` dovrebbe restituire un elemento `div`.
```js
assert.strictEqual(JSX.type, 'div');
```
Il `div` dovrebbe contenere un tag `br`.
```js
assert(Enzyme.shallow(JSX).find('br').length === 1);
```
Il `div` dovrebbe contenere un tag `hr`.
```js
assert(Enzyme.shallow(JSX).find('hr').length === 1);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(JSX, document.getElementById('root'))
```
## --seed-contents--
```jsx
const JSX = (
<div>
<h2>Welcome to React!</h2> <br >
<p>Be sure to close all tags!</p>
<hr >
</div>
);
```
# --solutions--
```jsx
const JSX = (
<div>
<h2>Welcome to React!</h2> <br />
<p>Be sure to close all tags!</p>
<hr />
</div>
);
```

View File

@ -0,0 +1,187 @@
---
id: 5a24c314108439a4d4036180
title: Ottimizzare il re-rendering con shouldComponentUpdate
challengeType: 6
forumTopicId: 301398
dashedName: optimize-re-renders-with-shouldcomponentupdate
---
# --description--
Finora, se un componente riceve un nuovo `state` o nuove `props`, avvia un re-rendering di sé stesso e di tutti i suoi figli. Questo normalmente va bene. Ma React fornisce un metodo per il ciclo di vita che puoi chiamare quando i componenti figli ricevono un nuovo `state` o `props`, e dichiarare specificamente se i componenti devono essere aggiornati o meno. Il metodo è `shouldComponentUpdate()`, e richiede `nextProps` e `nextState` come parametri.
Questo metodo è un modo utile per ottimizzare le prestazioni. Ad esempio, il comportamento predefinito è che il tuo componente rifà il render quando riceve nuove `props`, anche se le `props` non sono cambiate. È possibile utilizzare `shouldComponentUpdate()` per evitarlo confrontando le `props`. Il metodo deve restituire un valore `boolean` che dice a React se aggiornare o meno il componente. Puoi confrontare gli elementi attuali (`this.props`) con le nuove props (`nextProps`) per determinare se è necessario aggiornare o meno, e restituire `true` o `false` di conseguenza.
# --instructions--
Il metodo `shouldComponentUpdate()` viene aggiunto in un componente chiamato `OnlyEvens`. Attualmente, questo metodo restituisce `true` così `OnlyEvens` rifà il render ogni volta che riceve nuove `props`. Modifica il metodo in modo che `OnlyEvens` aggiorni solo se il `value` delle sue nuove props è pari. Fai clic sul pulsante `Add` e guarda l'ordine degli eventi nella console del browser mano a mano che vengono attivati durante il ciclo di vita.
# --hints--
Il componente `Controller` dovrebbe fare il rendering del componente figlio `OnlyEvens`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(Controller));
return (
mockedComponent.find('Controller').length === 1 &&
mockedComponent.find('OnlyEvens').length === 1
);
})()
);
```
Il metodo `shouldComponentUpdate` dovrebbe essere definito sul componente `OnlyEvens`.
```js
assert(
(() => {
const child = React.createElement(OnlyEvens)
.type.prototype.shouldComponentUpdate.toString()
.replace(/s/g, '');
return child !== 'undefined';
})()
);
```
Il componente `OnlyEvens` dovrebbe restituire un tag `h1` che presenta il valore di `this.props.value`.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(Controller));
const first = () => {
mockedComponent.setState({ value: 1000 });
return mockedComponent.find('h1').html();
};
const second = () => {
mockedComponent.setState({ value: 10 });
return mockedComponent.find('h1').html();
};
const firstValue = first();
const secondValue = second();
assert(firstValue === '<h1>1000</h1>' && secondValue === '<h1>10</h1>');
})();
```
`OnlyEvens` dovrebbe rifare il render solo quando `nextProps.value` è pari.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(Controller));
const first = () => {
mockedComponent.setState({ value: 8 });
return mockedComponent.find('h1').text();
};
const second = () => {
mockedComponent.setState({ value: 7 });
return mockedComponent.find('h1').text();
};
const third = () => {
mockedComponent.setState({ value: 42 });
return mockedComponent.find('h1').text();
};
const firstValue = first();
const secondValue = second();
const thirdValue = third();
assert(firstValue === '8' && secondValue === '8' && thirdValue === '42');
})();
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<Controller />, document.getElementById('root'));
```
## --seed-contents--
```jsx
class OnlyEvens extends React.Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(nextProps, nextState) {
console.log('Should I update?');
// Change code below this line
return true;
// Change code above this line
}
componentDidUpdate() {
console.log('Component re-rendered.');
}
render() {
return <h1>{this.props.value}</h1>;
}
}
class Controller extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
this.addValue = this.addValue.bind(this);
}
addValue() {
this.setState(state => ({
value: state.value + 1
}));
}
render() {
return (
<div>
<button onClick={this.addValue}>Add</button>
<OnlyEvens value={this.state.value} />
</div>
);
}
}
```
# --solutions--
```jsx
class OnlyEvens extends React.Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(nextProps, nextState) {
console.log('Should I update?');
// Change code below this line
return nextProps.value % 2 === 0;
// Change code above this line
}
componentDidUpdate() {
console.log('Component re-rendered.');
}
render() {
return <h1>{this.props.value}</h1>;
}
}
class Controller extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0
};
this.addValue = this.addValue.bind(this);
}
addValue() {
this.setState(state => ({
value: state.value + 1
}));
}
render() {
return (
<div>
<button onClick={this.addValue}>Add</button>
<OnlyEvens value={this.state.value} />
</div>
);
}
}
```

View File

@ -0,0 +1,112 @@
---
id: 5a24c314108439a4d403616c
title: Sovrascrivere le proprietà predefinite
challengeType: 6
forumTopicId: 301399
dashedName: override-default-props
---
# --description--
La possibilità di impostare delle proprietà predefinite è una caratteristica utile in React. Per sovrascrivere gli elementi predefiniti si devono impostare esplicitamente i valori delle proprietà per un componente.
# --instructions--
Il componente `ShoppingCart` ora presenta un componente figlio `Items`. Questo componente `Items` ha una proprietà di default `quantity` impostata all'intero `0`. Sovrascrivi la proprietà predefinita passando un valore di `10` per `quantity`.
**Nota:** Ricorda che la sintassi per aggiungere una proprietà a un componente è simile a quella degli attributi HTML. Tuttavia, poiché il valore per la `quantity` è un numero intero, non andrà tra virgolette ma dovrebbe essere racchiusa tra parentesi graffe. Ad esempio, `{100}`. Questa sintassi dice a JSX di interpretare il valore all'interno delle parentesi graffe direttamente come JavaScript.
# --hints--
Il componente `ShoppingCart` dovrebbe effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ShoppingCart));
return mockedComponent.find('ShoppingCart').length === 1;
})()
);
```
Il componente `Items` dovrebbe effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ShoppingCart));
return mockedComponent.find('Items').length === 1;
})()
);
```
Il componente `Items` dovrebbe avere una proprietà di `{ quantity: 10 }` passata dal componente `ShoppingCart`.
```js
(getUserInput) =>
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ShoppingCart));
return (
mockedComponent.find('Items').props().quantity == 10 &&
getUserInput('index')
.replace(/ /g, '')
.includes('<Itemsquantity={10}/>')
);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<ShoppingCart />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const Items = (props) => {
return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
}
Items.defaultProps = {
quantity: 0
}
class ShoppingCart extends React.Component {
constructor(props) {
super(props);
}
render() {
{ /* Change code below this line */ }
return <Items />
{ /* Change code above this line */ }
}
};
```
# --solutions--
```jsx
const Items = (props) => {
return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
}
Items.defaultProps = {
quantity: 0
}
class ShoppingCart extends React.Component {
constructor(props) {
super(props);
}
render() {
{ /* Change code below this line */ }
return <Items quantity = {10} />
{ /* Change code above this line */ }
}
};
```

View File

@ -0,0 +1,217 @@
---
id: 5a24c314108439a4d403617b
title: Passare una Callback come proprietà
challengeType: 6
forumTopicId: 301400
dashedName: pass-a-callback-as-props
---
# --description--
Puoi passare lo `state` come proprietà ai componenti figli, ma non sei limitato al passaggio dei dati. Puoi anche passare a un componente figlio delle funzioni di gestione o qualsiasi metodo definito su un componente React. In questo modo permetti ai componenti figli di interagire con i loro componenti genitori. Passi dei metodi a un figlio proprio come delle normali proprietà. Verrà assegnato un nome e potrai accedere a quel nome di metodo da `this.props` nel componente figlio.
# --instructions--
Ci sono tre componenti delineati nell'editor di codice. Il componente `MyApp` è il genitore che presenterà i componenti figli `GetInput` e `RenderInput`. Aggiungi il componente `GetInput` al metodo render in `MyApp`, poi passagli una proprietà chiamata `input` con valore di `inputValue` dallo `state` di `MyApp`. Crea anche una proprietà chiamata `handleChange` e passale il gestore di input `handleChange`.
Successivamente, aggiungi `RenderInput` al metodo render in `MyApp`, quindi crea una proprietà chiamata `input` e passale l'`inputValue` dallo `state`. Una volta terminato, potrai digitare nel campo `input` nel componente `GetInput`, che poi chiamerà il metodo di gestione nel suo genitore tramite le props. Questo aggiorna l'input nello `state` del genitore, che viene passato come proprietà ad entrambi i figli. Osserva come i dati scorrono tra i componenti e come l'unica fonte di verità rimane lo `state` del componente genitore. Certamente questo esempio è un po' limitato, ma dovrebbe bastare a illustrare come i dati e le callback possono essere passati tra i componenti di React.
# --hints--
Il componente `MyApp` dovrebbe effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
return mockedComponent.find('MyApp').length === 1;
})()
);
```
Il componente `GetInput` dovrebbe effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
return mockedComponent.find('GetInput').length === 1;
})()
);
```
Il componente `RenderInput` dovrebbe effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
return mockedComponent.find('RenderInput').length === 1;
})()
);
```
Il componente `GetInput` dovrebbe ricevere la proprietà `inputValue` dello stato di `MyApp` e contenere un elemento `input` che modifica lo stato di `MyApp`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
const state_1 = () => {
mockedComponent.setState({ inputValue: '' });
return waitForIt(() => mockedComponent.state());
};
const state_2 = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: 'TestInput' } });
return waitForIt(() => mockedComponent.state());
};
const updated_1 = await state_1();
const updated_2 = await state_2();
assert(updated_1.inputValue === '' && updated_2.inputValue === 'TestInput');
};
```
Il componente `RenderInput` dovrebbe ricevere la proprietà `inputValue` dello stato di `MyApp`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
const state_1 = () => {
mockedComponent.setState({ inputValue: 'TestName' });
return waitForIt(() => mockedComponent);
};
const updated_1 = await state_1();
assert(updated_1.find('p').text().includes('TestName'));
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyApp />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyApp extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
inputValue: event.target.value
});
}
render() {
return (
<div>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
class GetInput extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>Get Input:</h3>
<input
value={this.props.input}
onChange={this.props.handleChange}/>
</div>
);
}
};
class RenderInput extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>Input Render:</h3>
<p>{this.props.input}</p>
</div>
);
}
};
```
# --solutions--
```jsx
class MyApp extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
inputValue: event.target.value
});
}
render() {
return (
<div>
<GetInput
input={this.state.inputValue}
handleChange={this.handleChange}/>
<RenderInput
input={this.state.inputValue}/>
</div>
);
}
};
class GetInput extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>Get Input:</h3>
<input
value={this.props.input}
onChange={this.props.handleChange}/>
</div>
);
}
};
class RenderInput extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>Input Render:</h3>
<p>{this.props.input}</p>
</div>
);
}
};
```

View File

@ -0,0 +1,186 @@
---
id: 5a24c314108439a4d403616a
title: Passare un Array come proprietà
challengeType: 6
forumTopicId: 301401
dashedName: pass-an-array-as-props
---
# --description--
L'ultima sfida ha mostrato come trasferire le informazioni da un componente genitore a un componente figlio come `props` o proprietà. Questa sfida mostra come gli array possono essere passati come `props`. Per passare un array a un elemento JSX, esso deve essere trattato come JavaScript e avvolto in parentesi graffe.
```jsx
<ParentComponent>
<ChildComponent colors={["green", "blue", "red"]} />
</ParentComponent>
```
Il componente figlio ha quindi accesso alla proprietà array `colors`. I metodi sugli array come `join()` possono essere utilizzati quando si accede alla proprietà. `const ChildComponent = (props) => <p>{props.colors.join(', ')}</p>` Questo unirà tutti gli elementi `colors` dell'array in una stringa separata da virgole e produrrà: `<p>green, blue, red</p>` Più avanti vedremo altri metodi comuni per fare il rendering di array di dati in React.
# --instructions--
Nell'editor di codice ci sono i componenti `List` e `ToDo`. Quando si esegue il rendering di ogni `List` dal componente `ToDo`, deve essere passata una proprietà `tasks` assegnata a un array di attività da fare, ad esempio `["walk dog", "workout"]`. Quindi accedi a questo array `tasks` nel componente `List`, mostrandone il valore all'interno dell'elemento `p`. Usa `join(", ")` per visualizzare l'array `props.tasks` nell'elemento `p` come lista separata da virgole. L'elenco di oggi (Today) dovrebbe avere almeno 2 task e quella di domani (Tomorrow) dovrebbe avere almeno 3 task.
# --hints--
Il componente `ToDo` dovrebbe restituire un singolo `div` esterno.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ToDo));
return mockedComponent.children().first().type() === 'div';
})()
);
```
Il terzo figlio del componente `ToDo` dovrebbe essere un'istanza del componente `List`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ToDo));
return mockedComponent.children().first().childAt(2).name() === 'List';
})()
);
```
Il quinto figlio del componente `ToDo` dovrebbe essere un'istanza del componente `List`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ToDo));
return mockedComponent.children().first().childAt(4).name() === 'List';
})()
);
```
Entrambe le istanze del componente `List` dovrebbero avere una proprietà chiamata `tasks` e `tasks` dovrebbe essere di tipo array.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ToDo));
return (
Array.isArray(mockedComponent.find('List').get(0).props.tasks) &&
Array.isArray(mockedComponent.find('List').get(1).props.tasks)
);
})()
);
```
Il primo componente `List`, che rappresenta le attività per oggi, dovrebbe avere 2 o più elementi.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ToDo));
return mockedComponent.find('List').get(0).props.tasks.length >= 2;
})()
);
```
Il secondo componente `List`, che rappresenta le attività per domani, dovrebbe avere 3 o più elementi.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ToDo));
return mockedComponent.find('List').get(1).props.tasks.length >= 3;
})()
);
```
Il componente `List` dovrebbe presentare nel tag `p` il valore dalla proprietà `tasks`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ToDo));
return (
mockedComponent
.find('p')
.get(0)
.props.children.replace(/\s*,\s*/g, ',') ===
mockedComponent
.find('List')
.get(0)
.props.tasks.join(',')
.replace(/\s*,\s*/g, ',') &&
mockedComponent
.find('p')
.get(1)
.props.children.replace(/\s*,\s*/g, ',') ===
mockedComponent
.find('List')
.get(1)
.props.tasks.join(',')
.replace(/\s*,\s*/g, ',')
);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<ToDo />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const List = (props) => {
{ /* Change code below this line */ }
return <p>{}</p>
{ /* Change code above this line */ }
};
class ToDo extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>To Do Lists</h1>
<h2>Today</h2>
{ /* Change code below this line */ }
<List/>
<h2>Tomorrow</h2>
<List/>
{ /* Change code above this line */ }
</div>
);
}
};
```
# --solutions--
```jsx
const List= (props) => {
return <p>{props.tasks.join(', ')}</p>
};
class ToDo extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>To Do Lists</h1>
<h2>Today</h2>
<List tasks={['study', 'exercise']} />
<h2>Tomorrow</h2>
<List tasks={['call Sam', 'grocery shopping', 'order tickets']} />
</div>
);
}
};
```

View File

@ -0,0 +1,164 @@
---
id: 5a24c314108439a4d4036169
title: Passare proprietà a un componente funzionale senza stato
challengeType: 6
forumTopicId: 301402
dashedName: pass-props-to-a-stateless-functional-component
---
# --description--
Le sfide precedenti riguardavano la creazione e la composizione di elementi JSX, componenti funzionali e componenti ES6 di classe style in React. Con queste fondamenta, è il momento di guardare un'altra caratteristica molto comune in React: le **props**. In React, puoi passare props, o proprietà, a componenti figli. Diciamo che tu abbia un componente `App` che presenta un componente figlio chiamato `Welcome` che è un componente funzionale senza stato. Puoi passare a `Welcome` una proprietà `user` scrivendo:
```jsx
<App>
<Welcome user='Mark' />
</App>
```
Utilizzi degli **attributi HTML personalizzati** creati da te e passati da React al componente. In questo caso, la proprietà `user` che hai creato viene passata al componente `Welcome`. Dal momento che `Welcome` è un componente funzionale senza stato, ha accesso a questo valore in questo modo:
```jsx
const Welcome = (props) => <h1>Hello, {props.user}!</h1>
```
È comune chiamare questo valore `props` e quando si tratta di componenti funzionali senza stato, lo consideri fondamentalmente come un argomento per una funzione che restituisce JSX. Puoi accedere al valore dell'argomento nel corpo della funzione. Con i componenti di classe, vedrai che questo è un po' diverso.
# --instructions--
Nell'editor di codice ci sono i componenti `Calendar` e `CurrentDate`. Quando fai il rendering di `CurrentDate` dal componente `Calendar`, passagli una proprietà `date` assegnata alla data corrente dall'oggetto `Date` di JavaScript. Quindi accedi a questa `prop` nel componente `CurrentDate`, mostrandone il valore all'interno dei tag `p`. Nota che affinché i valori `prop` siano valutati come JavaScript, devono essere racchiusi tra parentesi graffe, ad esempio `date={Date()}`.
# --hints--
Il componente `Calendar` dovrebbe restituire un singolo elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(Calendar));
return mockedComponent.children().type() === 'div';
})()
);
```
Il secondo figlio del componente `Calendar` dovrebbe essere il componente `CurrentDate`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(Calendar));
return mockedComponent.children().childAt(1).name() === 'CurrentDate';
})()
);
```
Il componente `CurrentDate` dovrebbe avere una prop chiamata `date`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(Calendar));
return mockedComponent.children().childAt(1).props().date;
})()
);
```
La proprietà `date` di `CurrentDate` dovrebbe contenere una stringa di testo.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(Calendar));
const prop = mockedComponent.children().childAt(1).props().date;
return typeof prop === 'string' && prop.length > 0;
})()
);
```
La proprietà `date` dovrebbe essere generata chiamando `Date()`
```js
assert(/<CurrentDatedate={Date\(\)}\/>/.test(__helpers.removeWhiteSpace(code)));
```
Il componente `CurrentDate` dovrebbe presentare nel tag `p` il valore della proprietà `date`.
```js
let date = 'dummy date';
assert(
(function () {
const mockedComponent = Enzyme.mount(
React.createElement(CurrentDate, { date })
);
return mockedComponent.find('p').html().includes(date);
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<Calendar />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const CurrentDate = (props) => {
return (
<div>
{ /* Change code below this line */ }
<p>The current date is: </p>
{ /* Change code above this line */ }
</div>
);
};
class Calendar extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>What date is it?</h3>
{ /* Change code below this line */ }
<CurrentDate />
{ /* Change code above this line */ }
</div>
);
}
};
```
# --solutions--
```jsx
const CurrentDate = (props) => {
return (
<div>
{ /* Change code below this line */ }
<p>The current date is: {props.date}</p>
{ /* Change code above this line */ }
</div>
);
};
class Calendar extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>What date is it?</h3>
{ /* Change code below this line */ }
<CurrentDate date={Date()} />
{ /* Change code above this line */ }
</div>
);
}
};
```

View File

@ -0,0 +1,145 @@
---
id: 5a24c314108439a4d403617a
title: Passare State come Props ai componenti figli
challengeType: 6
forumTopicId: 301403
dashedName: pass-state-as-props-to-child-components
---
# --description--
Hai visto un sacco di esempi che hanno passato le proprietà a elementi JSX figli e a componenti React figli nelle sfide precedenti. Potresti chiederti da dove provengono quelle proprietà. Un modello comune è quello di avere un componente stateful contenente lo `state` importante per la tua app, che poi presenta i componenti figli. Vuoi che questi componenti abbiano accesso ad alcune parti di quello `state`che viene passato come props (proprietà).
Ad esempio, forse hai un componente `App` che presenta una `Navbar`, tra gli altri componenti. Nella tua `App` hai `state` che contiene molte informazioni dell'utente, ma la `Navbar` ha solo bisogno di accedere al nome utente dell'utente in modo da visualizzarlo. Passa quel pezzo di `state` al componente `Navbar` come una prop.
Questo modello illustra alcuni paradigmi importanti in React. Il primo è il *flusso di dati unidirezionale*. Lo stato scorre in una direzione lungo l'albero dei componenti della tua applicazione, dal componente genitore stateful ai componenti figli. I componenti figlio ricevono solo i dati di stato di cui hanno bisogno. Il secondo è che complesse app stateful possono essere suddivise in alcuni, o anche un singolo componente stateful. Il resto dei tuoi componenti semplicemente riceve lo stato dal genitore come props, e presenta un'interfaccia utente da quello stato. Si comincia col creare una separazione in cui la gestione dello stato viene gestita in una parte del codice e il rendering dell'interfaccia utente in un'altra. Questo principio di separazione della logica dello stato dalla logica dell'interfaccia utente è uno dei principi chiave di React. Quando viene utilizzato correttamente, rende la progettazione di applicazioni stateful complesse molto più facile da gestire.
# --instructions--
Il componente `MyApp` è stateful e presenta un componente `Navbar` come figlio. Passa la proprietà `name` del suo `state` al componente figlio, poi mostra il `name` nel tag `h1` che fa parte del metodo render di `Navbar`. `name` dovrebbe apparire dopo il testo `Hello, my name is:`.
# --hints--
Il componente `MyApp` dovrebbe eseguire il render con un componente `Navbar` al suo interno.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
return (
mockedComponent.find('MyApp').length === 1 &&
mockedComponent.find('Navbar').length === 1
);
})()
);
```
Il componente `Navbar` dovrebbe ricevere la proprietà `name` dello stato di `MyApp` come proprietà.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
const setState = () => {
mockedComponent.setState({ name: 'TestName' });
return waitForIt(() => mockedComponent.find('Navbar').props());
};
const navProps = await setState();
assert(navProps.name === 'TestName');
};
```
L'elemento `h1` in `Navbar` dovrebbe presentare la proprietà `name`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyApp));
const navH1Before = mockedComponent.find('Navbar').find('h1').text();
const setState = () => {
mockedComponent.setState({ name: 'TestName' });
return waitForIt(() => mockedComponent.find('Navbar').find('h1').text());
};
const navH1After = await setState();
assert(new RegExp('TestName').test(navH1After) && navH1After !== navH1Before);
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyApp />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyApp extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'CamperBot'
}
}
render() {
return (
<div>
{/* Change code below this line */}
<Navbar />
{/* Change code above this line */}
</div>
);
}
};
class Navbar extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
{/* Change code below this line */}
<h1>Hello, my name is: </h1>
{/* Change code above this line */}
</div>
);
}
};
```
# --solutions--
```jsx
class MyApp extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'CamperBot'
}
}
render() {
return (
<div>
<Navbar name={this.state.name}/>
</div>
);
}
};
class Navbar extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>Hello, my name is: {this.props.name}</h1>
</div>
);
}
};
```

View File

@ -0,0 +1,159 @@
---
id: 5a24c314108439a4d4036167
title: Presentare un componente di classe nel DOM
challengeType: 6
forumTopicId: 301404
dashedName: render-a-class-component-to-the-dom
---
# --description--
Potresti ricordare l'uso dell'API ReactDOM in una sfida precedente, usata per fare il render degli elementi JSX nel DOM. Il processo di rendering dei componenti di React sarà molto simile. Le poche sfide viste finora si sono concentrate su componenti e composizione, e il rendering è stato fatto per te dietro le quinte. Tuttavia, niente del codice React che scrivi sarà presentato nel DOM senza effettuare una chiamata all'API ReactDOM.
Ecco un ripasso della sintassi: `ReactDOM.render(componentToRender, targetNode)`. Il primo argomento è il componente React che si desidera presentare. Il secondo argomento è il nodo del DOM all'interno del quale si desidera fare il render di quel componente.
I componenti React sono passati in `ReactDOM.render()` in modo un po' diverso dagli elementi JSX. Per gli elementi JSX, passi il nome dell'elemento che desideri presentare. Tuttavia, per i componenti React, è necessario utilizzare la stessa sintassi come se si stesse presentando un componente nidificato, ad esempio `ReactDOM.render(<ComponentToRender />, targetNode)`. Si utilizza questa sintassi sia per i componenti di classe ES6 che per i componenti funzionali.
# --instructions--
I componenti `Fruits` e `Vegetables` sono definiti per te dietro le quinte. Presenta entrambi i componenti come figli del componente `TypesOfFood`, quindi presenta `TypesOfFood` nel DOM. C'è un `div` con `id='challenge-node'` pronto all'uso per te.
# --hints--
Il componente `TypesOfFood` dovrebbe restituire un singolo elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(TypesOfFood));
return mockedComponent.children().type() === 'div';
})()
);
```
Il componente `TypesOfFood` dovrebbe presentare il componente `Fruits` dopo l'elemento `h1`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(TypesOfFood));
return mockedComponent.children().childAt(1).name() === 'Fruits';
})()
);
```
Il componente `TypesOfFood` dovrebbe presentare il componente `Vegetables` dopo `Fruits`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(TypesOfFood));
return mockedComponent.children().childAt(2).name() === 'Vegetables';
})()
);
```
Il componente `TypesOfFood` dovrebbe essere presentato nel DOM all'interno del `div` con l'id `challenge-node`.
```js
assert(
(function () {
const html = document.getElementById('challenge-node').childNodes[0]
.innerHTML;
return (
html.includes(
'<div><h2>Fruits:</h2><h4>Non-Citrus:</h4><ul><li>Apples</li><li>Blueberries</li><li>Strawberries</li><li>Bananas</li></ul><h4>Citrus:</h4><ul><li>Lemon</li><li>Lime</li><li>Orange</li><li>Grapefruit</li></ul></div>'
) &&
html.includes(
'<div><h2>Vegetables:</h2><ul><li>Brussel Sprouts</li><li>Broccoli</li><li>Squash</li></ul></div>'
)
);
})()
);
```
# --seed--
## --before-user-code--
```jsx
const Fruits = () => {
return (
<div>
<h2>Fruits:</h2>
<h4>Non-Citrus:</h4>
<ul>
<li>Apples</li>
<li>Blueberries</li>
<li>Strawberries</li>
<li>Bananas</li>
</ul>
<h4>Citrus:</h4>
<ul>
<li>Lemon</li>
<li>Lime</li>
<li>Orange</li>
<li>Grapefruit</li>
</ul>
</div>
);
};
const Vegetables = () => {
return (
<div>
<h2>Vegetables:</h2>
<ul>
<li>Brussel Sprouts</li>
<li>Broccoli</li>
<li>Squash</li>
</ul>
</div>
);
};
```
## --seed-contents--
```jsx
class TypesOfFood extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>Types of Food:</h1>
{/* Change code below this line */}
{/* Change code above this line */}
</div>
);
}
};
// Change code below this line
```
# --solutions--
```jsx
class TypesOfFood extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>Types of Food:</h1>
{/* Change code below this line */}
<Fruits />
<Vegetables />
{/* Change code above this line */}
</div>
);
}
};
// Change code below this line
ReactDOM.render(<TypesOfFood />, document.getElementById('challenge-node'));
```

View File

@ -0,0 +1,303 @@
---
id: 5a24c314108439a4d4036188
title: Presentare condizionalmente dalle Props
challengeType: 6
forumTopicId: 301405
dashedName: render-conditionally-from-props
---
# --description--
Fino ad ora hai visto come usare `if/else`, `&&`, e l'operatore ternario (`condition ? expressionIfTrue : expressionIfFalse`) per fare decisioni condizionali su cosa e quando presentare. Tuttavia, c'è ancora un argomento importante da discutere che consente di combinare uno o tutti questi concetti con un'altra potente funzionalità di React: le props. Usare le proprietà (props) per presentare il codice condizionalmente è molto comune tra gli sviluppatori di React — cioè essi usano il valore di una determinata proprietà per prendere automaticamente delle decisioni su cosa presentare.
In questa sfida, configurerai un componente figlio per prendere decisioni di rendering basate sulle props. Utilizzerai anche l'operatore ternario, ma puoi vedere come molti degli altri concetti che sono stati trattati nelle ultime sfide potrebbero essere altrettanto utili in questo contesto.
# --instructions--
L'editor di codice ha due componenti che sono parzialmente definiti per te: un genitore chiamato `GameOfChance`, e un figlio chiamato `Results`. Essi sono utilizzati per creare un semplice gioco in cui l'utente preme un bottone per vedere se vince o perde.
In primo luogo, avrai bisogno di una semplice espressione che restituisca casualmente un valore diverso ogni volta che viene eseguita. Puoi usare `Math.random()`. Questo metodo restituisce un valore compreso tra `0` (incluso) e `1` (escluso) ogni volta che viene chiamato. Quindi, per avere delle quote 50/50, usa `Math.random() >= .5` nella tua espressione. Statisticamente parlando, questa espressione restituirà `true` il 50% delle volte, e `false` l'altro 50%. Nel metodo render, sostituisci `null` con l'espressione vista sopra per completare la dichiarazione della variabile.
Ora hai un'espressione che puoi usare per prendere una decisione casuale nel codice. Successivamente dovrai implementarla. Presenta il componente `Results` come figlio di `GameOfChance`, e passagli `expression` come una proprietà chiamata `fiftyFifty`. Nel componente `Results`, scrivi un'espressione ternaria per presentare l'elemento `h1` con il testo `You Win!` o `You Lose!` basato sulla proprietà `fiftyFifty` che viene passata da `GameOfChance`. Infine, assicurati che il metodo `handleClick()` stia contando correttamente ogni turno in modo che l'utente sappia quante volte ha giocato. Questo serve anche a far sapere all'utente che il componente è stato effettivamente aggiornato nel caso in cui vinca o perda due volte di fila.
# --hints--
Il componente `GameOfChance` dovrebbe esistere e essere presentato nella pagina.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).find('GameOfChance').length,
1
);
```
`GameOfChance` dovrebbe restituire un singolo elemento `button`.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).find('button').length,
1
);
```
`GameOfChance` dovrebbe restituire una singola istanza del componente `Results`, che ha una proprietà chiamata `fiftyFifty`.
```js
assert(
Enzyme.mount(React.createElement(GameOfChance)).find('Results').length ===
1 &&
Enzyme.mount(React.createElement(GameOfChance))
.find('Results')
.props()
.hasOwnProperty('fiftyFifty') === true
);
```
Lo stato di `GameOfChance` dovrebbe essere inizializzato con una proprietà `counter` impostata su un valore di `1`.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).state().counter,
1
);
```
Quando il componente `GameOfChance` viene presentato per la prima volta nel DOM, dovrebbe essere restituito un elemento `p` con il testo interno di `Turn: 1`.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).find('p').text(),
'Turn: 1'
);
```
Ogni volta che viene fatto click sul pulsante, lo stato del contatore deve essere incrementato di un valore di 1, e nel DOM dovrebbe essere presentato un singolo elemento `p` che contiene il testo `Turn: N`, dove `N` è il valore dello stato del contatore.
```js
(() => {
const comp = Enzyme.mount(React.createElement(GameOfChance));
const simulate = () => {
comp.find('button').simulate('click');
};
const result = () => ({
count: comp.state('counter'),
text: comp.find('p').text()
});
const _1 = () => {
simulate();
return result();
};
const _2 = () => {
simulate();
return result();
};
const _3 = () => {
simulate();
return result();
};
const _4 = () => {
simulate();
return result();
};
const _5 = () => {
simulate();
return result();
};
const _1_val = _1();
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
const _5_val = _5();
assert(
_1_val.count === 2 &&
_1_val.text === 'Turn: 2' &&
_2_val.count === 3 &&
_2_val.text === 'Turn: 3' &&
_3_val.count === 4 &&
_3_val.text === 'Turn: 4' &&
_4_val.count === 5 &&
_4_val.text === 'Turn: 5' &&
_5_val.count === 6 &&
_5_val.text === 'Turn: 6'
);
})();
```
Quando il componente `GameOfChance` viene montato per la prima volta nel DOM e ogni volta che il bottone viene cliccato successivamente, dovrebbe essere restituito un singolo elemento `h1` che scrive casualmente `You Win!` o `You Lose!`.
```js
(() => {
const comp = Enzyme.mount(React.createElement(GameOfChance));
const simulate = () => {
comp.find('button').simulate('click');
};
const result = () => ({
h1: comp.find('h1').length,
text: comp.find('h1').text()
});
const _1 = result();
const _2 = () => {
simulate();
return result();
};
const _3 = () => {
simulate();
return result();
};
const _4 = () => {
simulate();
return result();
};
const _5 = () => {
simulate();
return result();
};
const _6 = () => {
simulate();
return result();
};
const _7 = () => {
simulate();
return result();
};
const _8 = () => {
simulate();
return result();
};
const _9 = () => {
simulate();
return result();
};
const _10 = () => {
simulate();
return result();
};
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
const _5_val = _5();
const _6_val = _6();
const _7_val = _7();
const _8_val = _8();
const _9_val = _9();
const _10_val = _10();
const __text = new Set([
_1.text,
_2_val.text,
_3_val.text,
_4_val.text,
_5_val.text,
_6_val.text,
_7_val.text,
_8_val.text,
_9_val.text,
_10_val.text
]);
const __h1 = new Set([
_1.h1,
_2_val.h1,
_3_val.h1,
_4_val.h1,
_5_val.h1,
_6_val.h1,
_7_val.h1,
_8_val.h1,
_9_val.h1,
_10_val.h1
]);
assert(__text.size === 2 && __h1.size === 1);
})();
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<GameOfChance />, document.getElementById('root'));
```
## --seed-contents--
```jsx
class Results extends React.Component {
constructor(props) {
super(props);
}
render() {
{/* Change code below this line */}
return <h1></h1>;
{/* Change code above this line */}
}
}
class GameOfChance extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => {
// Complete the return statement:
return {
counter: prevState
}
});
}
render() {
const expression = null; // Change this line
return (
<div>
<button onClick={this.handleClick}>Play Again</button>
{/* Change code below this line */}
{/* Change code above this line */}
<p>{'Turn: ' + this.state.counter}</p>
</div>
);
}
}
```
# --solutions--
```jsx
class Results extends React.Component {
constructor(props) {
super(props);
}
render() {
return <h1>{this.props.fiftyFifty ? 'You Win!' : 'You Lose!'}</h1>;
}
}
class GameOfChance extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => {
return {
counter: prevState.counter + 1
}
});
}
render() {
const expression = Math.random() >= 0.5;
return (
<div>
<button onClick={this.handleClick}>Play Again</button>
<Results fiftyFifty={expression} />
<p>{'Turn: ' + this.state.counter}</p>
</div>
);
}
}
```

View File

@ -0,0 +1,75 @@
---
id: 5a24bbe0dba28a8d3cbd4c5f
title: Presentare gli elementi HTML nel DOM
challengeType: 6
forumTopicId: 301406
dashedName: render-html-elements-to-the-dom
---
# --description--
Finora, hai imparato che JSX è uno strumento utile per scrivere HTML leggibile all'interno di JavaScript. Con React, possiamo presentare questo JSX direttamente nel DOM HTML utilizzando l'API di rendering di React conosciuta come ReactDOM.
ReactDOM offre un metodo semplice per presentare gli elementi React nel DOM che appare così: `ReactDOM.render(componentToRender, targetNode)`, dove il primo argomento è l'elemento React o il componente che si desidera presentare, e il secondo argomento è il nodo DOM nel quale si desidera visualizzare il componente.
Come ci si aspetterebbe, `ReactDOM.render()` deve essere chiamato dopo le dichiarazioni degli elementi JSX, proprio come è necessario dichiarare le variabili prima di usarle.
# --instructions--
L'editor di codice contiene un semplice componente JSX. Usa il metodo `ReactDOM.render()` per presentare questo componente nella pagina. Puoi passare gli elementi JSX che hai definito direttamente come primo argomento e utilizzare `document.getElementById()` per selezionare il nodo DOM nel quale fare il render. C'è un `div` con `id='challenge-node'` pronto all'uso per te. Assicurati di non modificare la costante `JSX`.
# --hints--
La costante `JSX` dovrebbe restituire un elemento `div`.
```js
assert(JSX.type === 'div');
```
Il `div` dovrebbe contenere un tag `h1` come primo elemento.
```js
assert(JSX.props.children[0].type === 'h1');
```
Il `div` dovrebbe contenere un tag `p` come secondo elemento.
```js
assert(JSX.props.children[1].type === 'p');
```
L'elemento JSX fornito dovrebbe essere presentato nel nodo DOM con id `challenge-node`.
```js
assert(
document.getElementById('challenge-node').childNodes[0].innerHTML ===
'<h1>Hello World</h1><p>Lets render this to the DOM</p>'
);
```
# --seed--
## --seed-contents--
```jsx
const JSX = (
<div>
<h1>Hello World</h1>
<p>Lets render this to the DOM</p>
</div>
);
// Change code below this line
```
# --solutions--
```jsx
const JSX = (
<div>
<h1>Hello World</h1>
<p>Lets render this to the DOM</p>
</div>
);
// Change code below this line
ReactDOM.render(JSX, document.getElementById('challenge-node'));
```

View File

@ -0,0 +1,76 @@
---
id: 5a24c314108439a4d403618d
title: Presentare React nel server con renderToString
challengeType: 6
forumTopicId: 301407
dashedName: render-react-on-the-server-with-rendertostring
---
# --description--
Finora, hai presentato i componenti React sul client. Questo è quello che farai normalmente. Tuttavia, ci sono alcuni casi di utilizzo in cui ha senso presentare un componente React sul server. Dato che React è una libreria di visualizzazione JavaScript ed è possibile eseguire JavaScript sul server con Node, questo è possibile. Infatti, React fornisce un metodo `renderToString()` che puoi usare a questo scopo.
Ci sono due ragioni chiave per cui il rendering sul server può essere utilizzato in un'app del mondo reale. In primo luogo, senza fare questo, le tue applicazioni React consisterebbero in un file HTML relativamente vuoto e in un grande pacchetto di JavaScript da caricare inizialmente sul browser. Questo potrebbe non essere ideale per i motori di ricerca che stanno cercando di indicizzare il contenuto delle tue pagine in modo che le persone possano trovarti. Se si esegue il rendering del markup HTML iniziale sul server e lo si invia al client, il caricamento iniziale della pagina conterrà tutti i markup della pagina che possono essere letti dai motori di ricerca. In secondo luogo, questo crea un'esperienza di caricamento iniziale della pagina più veloce perché l'HTML presentato è più piccolo del codice JavaScript dell'intera app. React sarà comunque in grado di riconoscere la tua app e gestirla dopo il caricamento iniziale.
# --instructions--
Il metodo `renderToString()` è fornito su `ReactDOMServer`, disponibile qui come oggetto globale. Il metodo richiede un argomento che è un elemento di React. Usa questo per presentare `App` in una stringa.
# --hints--
Il componente `App` dovrebbe fare il rendering in una stringa usando `ReactDOMServer.renderToString`.
```js
(getUserInput) =>
assert(
getUserInput('index')
.replace(/ /g, '')
.includes('ReactDOMServer.renderToString(<App/>)') &&
Enzyme.mount(React.createElement(App)).children().name() === 'div'
);
```
# --seed--
## --before-user-code--
```jsx
var ReactDOMServer = { renderToString(x) { return null; } };
```
## --after-user-code--
```jsx
ReactDOM.render(<App />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return <div/>
}
};
// Change code below this line
```
# --solutions--
```jsx
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return <div/>
}
};
// Change code below this line
ReactDOMServer.renderToString(<App/>);
```

View File

@ -0,0 +1,119 @@
---
id: 5a24c314108439a4d4036172
title: Presentare lo stato nell'interfaccia utente in un altro modo
challengeType: 6
forumTopicId: 301408
dashedName: render-state-in-the-user-interface-another-way
---
# --description--
C'è un altro modo per accedere allo `state` in un componente. Nel metodo `render()`, prima dell'istruzione `return`, è possibile scrivere direttamente del JavaScript. Ad esempio, è possibile dichiarare funzioni, accedere ai dati da `state` o `props`, eseguire calcoli su questi dati, e così via. Poi, puoi assegnare qualsiasi dato alle variabili a cui hai accesso nell'istruzione `return`.
# --instructions--
Nel metodo render di `MyComponent`, definisci una `const` chiamata `name` e impostala al valore di name nello `state` del componente. Poiché in questa parte del codice è possibile scrivere direttamente in JavaScript, non è necessario racchiudere questo riferimento tra parentesi graffe.
Successivamente, nell'istruzione return, presenta questo valore in un tag `h1` utilizzando la variabile `name`. Ricorda però che nell'istruzione return dovrai utilizzare la sintassi JSX (parentesi graffe per il JavaScript).
# --hints--
`MyComponent` dovrebbe avere una chiave `name` con valore `freeCodeCamp` memorizzato nel suo stato.
```js
assert(
Enzyme.mount(React.createElement(MyComponent)).state('name') ===
'freeCodeCamp'
);
```
`MyComponent` dovrebbe presentare un'intestazione `h1` racchiusa in un singolo `div`.
```js
assert(
/<div><h1>.*<\/h1><\/div>/.test(
Enzyme.mount(React.createElement(MyComponent)).html()
)
);
```
Il tag `h1` presentato dovrebbe includere un riferimento a `{name}`.
```js
(getUserInput) =>
assert(/<h1>\n*\s*\{\s*name\s*\}\s*\n*<\/h1>/.test(getUserInput('index')));
```
L'intestazione `h1` dovrebbe contenere testo presentato dallo stato del componente.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const first = () => {
mockedComponent.setState({ name: 'TestName' });
return waitForIt(() => mockedComponent.html());
};
const firstValue = await first();
assert(firstValue === '<div><h1>TestName</h1></div>');
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'freeCodeCamp'
}
}
render() {
// Change code below this line
// Change code above this line
return (
<div>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'freeCodeCamp'
}
}
render() {
// Change code below this line
const name = this.state.name;
// Change code above this line
return (
<div>
{ /* Change code below this line */ }
<h1>{name}</h1>
{ /* Change code above this line */ }
</div>
);
}
};
```

View File

@ -0,0 +1,113 @@
---
id: 5a24c314108439a4d4036171
title: Presentare lo stato nell'interfaccia utente
challengeType: 6
forumTopicId: 301409
dashedName: render-state-in-the-user-interface
---
# --description--
Una volta definito lo stato iniziale di un componente, è possibile visualizzarne qualsiasi parte nell'interfaccia utente che viene presentata. Se un componente è stateful, avrà sempre accesso ai dati dello `state` nel suo metodo `render()`. È possibile accedere ai dati con `this.state`.
Se desideri accedere a un valore di stato all'interno del `return` del metodo render, devi racchiudere il valore in parentesi graffe.
`state` è una delle caratteristiche più potenti dei componenti di React. Ti permette di tracciare dati importanti nella tua app e presentare un'interfaccia utente in risposta alle modifiche di questi dati. Se i tuoi dati cambiano, la tua interfaccia utente cambierà. React utilizza quello che viene chiamato un DOM (Document Object Model) virtuale, per tenere traccia dei cambiamenti dietro le quinte. Quando lo stato dei dati si aggiorna, si attiva un re-render dei componenti che utilizzano tali dati - compresi i componenti figli che hanno ricevuto i dati come proprietà. React aggiorna il DOM, ma solo se necessario. Questo significa che non devi preoccuparti di cambiare il DOM. Semplicemente dichiari come dovrebbe apparire l'interfaccia utente.
Nota che se fai un componente stateful, nessun altro componente è a conoscenza del suo `state`. Il suo `state` è completamente incapsulato, o locale a quel componente, a meno che non passi i dati di stato a un componente figlio come `props`. Questa nozione di `state` incapsulato è molto importante perché permette di scrivere una certa logica, e poi di avere quella logica contenuta e isolata in un unico punto del tuo codice.
# --instructions--
Nell'editor di codice, `MyComponent` è già stateful. Definisci un tag `h1` nel metodo render del componente che presenta il valore di `name` prendendolo dallo stato del componente.
**Nota:** L'elemento `h1` dovrebbe presentare solo il valore dallo `state` e nient'altro. In JSX, qualsiasi codice che scrivi tra parentesi graffe `{ }` sarà trattato come JavaScript. Quindi, per accedere al valore dallo `state` basta racchiudere il riferimento nelle parentesi graffe.
# --hints--
`MyComponent` dovrebbe avere una chiave `name` con valore `freeCodeCamp` memorizzato nel suo stato.
```js
assert(
Enzyme.mount(React.createElement(MyComponent)).state('name') ===
'freeCodeCamp'
);
```
`MyComponent` dovrebbe presentare un'intestazione `h1` racchiusa in un singolo `div`.
```js
assert(
/<div><h1>.*<\/h1><\/div>/.test(
Enzyme.mount(React.createElement(MyComponent)).html()
)
);
```
L'intestazione `h1` dovrebbe contenere solo testo presentato dallo stato del componente.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const first = () => {
mockedComponent.setState({ name: 'TestName' });
return waitForIt(() => mockedComponent.html());
};
const firstValue = await first();
const getValue = firstValue.replace(/\s/g, '');
assert(getValue === '<div><h1>TestName</h1></div>');
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'freeCodeCamp'
}
}
render() {
return (
<div>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'freeCodeCamp'
}
}
render() {
return (
<div>
{ /* Change code below this line */ }
<h1>{this.state.name}</h1>
{ /* Change code above this line */ }
</div>
);
}
};
```

View File

@ -0,0 +1,155 @@
---
id: 5a24c314108439a4d4036184
title: Presentare con una condizione If-Else
challengeType: 6
forumTopicId: 301410
dashedName: render-with-an-if-else-condition
---
# --description--
Un'altra applicazione dell'uso di JavaScript per controllare la vista presentata è quella di legare gli elementi che sono presentati ad una condizione. Quando la condizione è vera, una vista viene presentata. Quando è falsa, viene presentata una vista diversa. Puoi farlo con un comando `if/else` standard nel metodo `render()` di un componente React.
# --instructions--
MyComponent contiene un `boolean` nel suo stato che traccia se si desidera o meno visualizzare qualche elemento nell'interfaccia utente. Il `button` commuta lo stato di questo valore. Attualmente, esso presenta la stessa interfaccia utente ogni volta. Riscrivi il metodo `render()` con un'istruzione `if/else` in modo che se `display` è `true`, restituisca il markup corrente. Altrimenti, restituisci il markup senza l'elemento `h1`.
**Nota:** Devi scrivere un `if/else` per superare i test. L'uso dell'operatore ternario non supererà i test qui, anche se sarebbe corretto.
# --hints--
`MyComponent` dovrebbe esistere ed effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.find('MyComponent').length === 1;
})()
);
```
Quando `display` è impostato a `true`, dovrebbero essere presentati un `div`, un `button` e un `h1`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const state_1 = () => {
mockedComponent.setState({ display: true });
return waitForIt(() => mockedComponent);
};
const updated = await state_1();
assert(
mockedComponent.find('div').length === 1 &&
mockedComponent.find('div').children().length === 2 &&
mockedComponent.find('button').length === 1 &&
mockedComponent.find('h1').length === 1
);
};
```
Quando `display` è impostato su `false`, dovrebbero essere presentati solo un `div` e un `button`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const state_1 = () => {
mockedComponent.setState({ display: false });
return waitForIt(() => mockedComponent);
};
const updated = await state_1();
assert(
mockedComponent.find('div').length === 1 &&
mockedComponent.find('div').children().length === 1 &&
mockedComponent.find('button').length === 1 &&
mockedComponent.find('h1').length === 0
);
};
```
Il metodo render dovrebbe utilizzare un'istruzione `if/else` per controllare la condizione di `this.state.display`.
```js
(getUserInput) =>
assert(
getUserInput('index').includes('if') &&
getUserInput('index').includes('else')
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
display: true
}
this.toggleDisplay = this.toggleDisplay.bind(this);
}
toggleDisplay() {
this.setState((state) => ({
display: !state.display
}));
}
render() {
// Change code below this line
return (
<div>
<button onClick={this.toggleDisplay}>Toggle Display</button>
<h1>Displayed!</h1>
</div>
);
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
display: true
}
this.toggleDisplay = this.toggleDisplay.bind(this);
}
toggleDisplay() {
this.setState((state) => ({
display: !state.display
}));
}
render() {
// Change code below this line
if (this.state.display) {
return (
<div>
<button onClick={this.toggleDisplay}>Toggle Display</button>
<h1>Displayed!</h1>
</div>
);
} else {
return (
<div>
<button onClick={this.toggleDisplay}>Toggle Display</button>
</div>
);
}
}
};
```

View File

@ -0,0 +1,145 @@
---
id: 5a24c314108439a4d403616f
title: Ripasso dell'uso delle Props con componenti funzionali senza stato
challengeType: 6
forumTopicId: 301411
dashedName: review-using-props-with-stateless-functional-components
---
# --description--
Fatta eccezione per l'ultima sfida, hai sempre passato le props a componenti funzionali senza stato. Questi componenti agiscono come funzioni pure. Accettano le props come input e restituiscono la stessa vista ogni volta che vengono passate le stesse proprietà. Potresti chiederti cosa sia lo stato e la prossima sfida lo spiegherà con maggiore dettaglio. Prima però, ecco un ripasso della terminologia per i componenti.
Un *componente funzionale senza stato* è una qualsiasi funzione che accetta props e restituisce JSX. Un *componente senza stato*, d'altra parte, è una classe che estende `React.Component`, ma non utilizza lo stato interno (coperto nella prossima sfida). Infine, un *componente stateful* è un componente di classe che mantiene il proprio stato interno. Spesso si fa riferimento ai componenti stateful chiamandoli semplicemente componenti o componenti React.
Un modello comune è quello di cercare di minimizzare l'estensione dello stato e di creare componenti funzionali senza stato, laddove possibile. Questo aiuta a contenere la gestione dello stato in un'area specifica della tua applicazione. A sua volta, questo migliora lo sviluppo e la manutenzione della tua app rendendo più facile seguire come le modifiche allo stato influenzano il suo comportamento.
# --instructions--
L'editor di codice ha un componente `CampSite` che presenta un componente `Camper` come figlio. Definisci il componente `Camper` e assegnagli la proprietà di default `{ name: 'CamperBot' }`. All'interno del componente `Camper`, presenta il codice che vuoi, ma assicurati di avere un elemento `p` che include solo il valore del `name` che viene passato come `prop`. Infine, definisci `propTypes` nel componente `Camper` in modo che richieda che `name` venga fornito come prop verificando che sia di tipo `string`.
# --hints--
Il componente `CampSite` dovrebbe effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(CampSite));
return mockedComponent.find('CampSite').length === 1;
})()
);
```
Il componente `Camper` dovrebbe effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(CampSite));
return mockedComponent.find('Camper').length === 1;
})()
);
```
Il componente `Camper` dovrebbe includere delle props predefinite che assegnano la stringa `CamperBot` alla chiave `name`.
```js
assert(
/Camper.defaultProps={name:(['"`])CamperBot\1,?}/.test(
__helpers.removeWhiteSpace(code)
)
);
```
Il componente `Camper` dovrebbe includere tipi di prop che richiedono che la proprietà `name` sia di tipo `string`.
```js
assert(
/Camper.propTypes={name:PropTypes.string.isRequired,?}/.test(
__helpers.removeWhiteSpace(code)
)
);
```
Il componente `Camper` dovrebbe contenere un elemento `p` che abbia come unico testo la proprietà `name`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(CampSite));
return (
mockedComponent.find('p').text() ===
mockedComponent.find('Camper').props().name
);
})()
);
```
# --seed--
## --before-user-code--
```jsx
var PropTypes = {
string: { isRequired: true }
};
```
## --after-user-code--
```jsx
ReactDOM.render(<CampSite />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class CampSite extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Camper/>
</div>
);
}
};
// Change code below this line
```
# --solutions--
```jsx
class CampSite extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Camper/>
</div>
);
}
};
// Change code below this line
const Camper = (props) => {
return (
<div>
<p>{props.name}</p>
</div>
);
};
Camper.propTypes = {
name: PropTypes.string.isRequired
};
Camper.defaultProps = {
name: 'CamperBot'
};
```

View File

@ -0,0 +1,143 @@
---
id: 5a24c314108439a4d4036173
title: Impostare lo stato con this.setState
challengeType: 6
forumTopicId: 301412
dashedName: set-state-with-this-setstate
---
# --description--
Le sfide precedenti riguardavano il componente `state` e come inizializzare lo stato nel `constructor`. C'è anche un modo per cambiare lo `state` del componente. React fornisce un metodo per l'aggiornamento dello `state` del componente chiamato `setState`. Chiamerai il metodo `setState` all'interno della classe component in questo modo: `this.setState()`, passandogli un oggetto con coppie chiave-valore. Le chiavi sono le proprietà dello stato e i valori sono i dati dello stato aggiornato. Per esempio, se stessimo memorizzando uno `username` nello stato e volessimo aggiornarlo, potremmo fare così:
```jsx
this.setState({
username: 'Lewis'
});
```
React si aspetta che tu non modifichi mai lo `state` direttamente: usa sempre `this.setState()` quando si verificano cambiamenti di stato. Inoltre, dovresti notare che React può raggruppare più aggiornamenti di stato al fine di migliorare le prestazioni. Ciò significa che gli aggiornamenti di stato attraverso il metodo `setState` possono essere asincroni. C'è una sintassi alternativa per il metodo `setState` che fornisce un modo per aggirare questo problema. Questo raramente è necessario, ma è bene tenerlo in mente! Consulta la [Documentazione di React](https://facebook.github.io/react/docs/state-and-lifecycle.html) per ulteriori dettagli.
# --instructions--
C'è un elemento `button` nell'editor di codice che ha un gestore `onClick()`. Questo gestore viene attivato quando il `button` riceve un evento click nel browser, ed esegue il metodo `handleClick` definito in `MyComponent`. All'interno del metodo `handleClick`, aggiorna lo `state` del componente usando `this.setState()`. Imposta la proprietà `name` in `state` in modo che sia uguale alla stringa `React Rocks!`.
Fai clic sul bottone e guarda l'aggiornamento della presentazione dello stato. Non preoccuparti se ancora non capisci completamente come funziona il codice di gestione del click. Lo vedremo nelle prossime sfide.
# --hints--
Lo stato di `MyComponent` dovrebbe essere inizializzato con la coppia chiave/valore `{ name: Initial State }`.
```js
assert(
Enzyme.mount(React.createElement(MyComponent)).state('name') ===
'Initial State'
);
```
`MyComponent` dovrebbe presentare un'intestazione `h1`.
```js
assert(Enzyme.mount(React.createElement(MyComponent)).find('h1').length === 1);
```
L'intestazione `h1` dovrebbe contenere testo presentato dallo stato del componente.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const first = () => {
mockedComponent.setState({ name: 'TestName' });
return waitForIt(() => mockedComponent.html());
};
const firstValue = await first();
assert(/<h1>TestName<\/h1>/.test(firstValue));
};
```
Chiamando il metodo `handleClick` su `MyComponent` si dovrebbe impostare la proprietà name nello stato sulla stringa `React Rocks!`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const first = () => {
mockedComponent.setState({ name: 'Before' });
return waitForIt(() => mockedComponent.state('name'));
};
const second = () => {
mockedComponent.instance().handleClick();
return waitForIt(() => mockedComponent.state('name'));
};
const firstValue = await first();
const secondValue = await second();
assert(firstValue === 'Before' && secondValue === 'React Rocks!');
};
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Initial State'
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// Change code below this line
// Change code above this line
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click Me</button>
<h1>{this.state.name}</h1>
</div>
);
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Initial State'
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// Change code below this line
this.setState({
name: 'React Rocks!'
});
// Change code above this line
}
render() {
return (
<div>
<button onClick = {this.handleClick}>Click Me</button>
<h1>{this.state.name}</h1>
</div>
);
}
};
```

View File

@ -0,0 +1,146 @@
---
id: 5a24c314108439a4d4036185
title: Usare && per un condizionale più conciso
challengeType: 6
forumTopicId: 301413
dashedName: use--for-a-more-concise-conditional
---
# --description--
Le istruzioni `if/else` hanno funzionato nell'ultima sfida, ma c'è un modo più conciso per raggiungere lo stesso risultato. Immagina di dover tracciare diverse condizioni in un componente e di volere che elementi differenti siano presentati a seconda di ciascuna di queste condizioni. Se scrivi un sacco di istruzioni `else if` per restituire interfacce utente leggermente diverse, puoi dover ripetere il codice lasciando spazio a degli errori. Puoi invece utilizzare l'operatore logico `&&` per eseguire la logica condizionale in modo più conciso. Questo è possibile perché si desidera controllare se una condizione è `true`, e se è così, restituire qualche markup. Ecco un esempio:
```jsx
{condition && <p>markup</p>}
```
Se la `condition` è `true`, il markup verrà restituito. Se la condizione è `false`, l'operazione restituirà immediatamente `false` dopo aver valutato la `condition` e non restituirà nulla. Puoi includere queste istruzioni direttamente nel tuo JSX e legando più condizioni insieme scrivendo `&&` dopo ognuna. Questo ti permette di gestire una logica condizionale più complessa nel tuo metodo `render()` senza ripetere un sacco di codice.
# --instructions--
Risolvi nuovamente l'esempio precedente, in modo che `h1` venga presentato solo se `display` è `true`, ma usa l'operatore logico `&&` invece di un'istruzione `if/else`.
# --hints--
`MyComponent` dovrebbe esistere ed effettuare il render.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.find('MyComponent').length;
})()
);
```
Quando `display` è impostato a `true`, dovrebbero essere presentati un `div`, un `button` e un `h1`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const state_1 = () => {
mockedComponent.setState({ display: true });
return waitForIt(() => mockedComponent);
};
const updated = await state_1();
assert(
updated.find('div').length === 1 &&
updated.find('div').children().length === 2 &&
updated.find('button').length === 1 &&
updated.find('h1').length === 1
);
};
```
Quando `display` è impostato su `false`, dovrebbero essere presentati solo un `div` e un `button`.
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const state_1 = () => {
mockedComponent.setState({ display: false });
return waitForIt(() => mockedComponent);
};
const updated = await state_1();
assert(
updated.find('div').length === 1 &&
updated.find('div').children().length === 1 &&
updated.find('button').length === 1 &&
updated.find('h1').length === 0
);
};
```
Il metodo render dovrebbe utilizzare l'operatore logico `&&` per controllare la condizione di `this.state.display`.
```js
(getUserInput) => assert(getUserInput('index').includes('&&'));
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
display: true
}
this.toggleDisplay = this.toggleDisplay.bind(this);
}
toggleDisplay() {
this.setState(state => ({
display: !state.display
}));
}
render() {
// Change code below this line
return (
<div>
<button onClick={this.toggleDisplay}>Toggle Display</button>
<h1>Displayed!</h1>
</div>
);
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
display: true
}
this.toggleDisplay = this.toggleDisplay.bind(this);
}
toggleDisplay() {
this.setState(state => ({
display: !state.display
}));
}
render() {
// Change code below this line
return (
<div>
<button onClick={this.toggleDisplay}>Toggle Display</button>
{this.state.display && <h1>Displayed!</h1>}
</div>
);
}
};
```

View File

@ -0,0 +1,280 @@
---
id: 5a24c314108439a4d4036187
title: Usare un'espressione ternaria per il rendering condizionale
challengeType: 6
forumTopicId: 301414
dashedName: use-a-ternary-expression-for-conditional-rendering
---
# --description--
Prima di passare alle tecniche di rendering dinamiche, c'è un ultimo modo per utilizzare le condizionali JavaScript integrate per presentare quello che vuoi: l'<dfn>operatore ternario</dfn>. L'operatore ternario è spesso utilizzato come scorciatoia per le istruzioni `if/else` in JavaScript. Non è robusto come le tradizionali istruzioni `if/else`, ma è molto popolare tra gli sviluppatori React. Uno dei motivi è che per come JSX è compilato, le istruzioni `if/else` non possono essere inserite direttamente nel codice JSX. Potresti averlo notato un paio di sfide fa — quando era richiesta un'istruzione `if/else`, era sempre inserita *fuori* dall'istruzione `return`. Le espressioni ternarie possono essere un'ottima alternativa se vuoi implementare una logica condizionale all'interno del tuo JSX. Ricordiamo che un operatore ternario ha tre parti, ma è possibile combinare diverse espressioni ternarie insieme. Ecco la sintassi di base:
```jsx
condition ? expressionIfTrue : expressionIfFalse;
```
# --instructions--
L'editor di codice ha tre costanti definite nel metodo `render()` del componente `CheckUserAge`. Si chiamano `buttonOne`, `buttonTwo`e `buttonThree`. Ad ognuno di questi viene assegnata una semplice espressione JSX che rappresenta un elemento button. Innanzitutto, inizializza lo stato di `CheckUserAge` con `input` e `userAge` entrambi impostati su una stringa vuota.
Una volta che il componente sta presentando delle informazioni sulla pagina, gli utenti dovrebbero avere un modo per interagire con esso. All'interno dell'istruzione `return` del componente, imposta un'espressione ternaria che implementa la seguente logica: quando la pagina viene caricata inizialmente, presenta il pulsante di invio, `buttonOne`, sulla pagina. Poi, quando un utente inserisce la sua età e fa click sul bottone, presenta un pulsante diverso in base all'età. Se un utente inserisce un numero inferiore a `18`, presenta `buttonThree`. Se un utente inserisce un numero maggiore o uguale a `18`, presenta `buttonTwo`.
# --hints--
Il componente `CheckUserAge` dovrebbe presentare un singolo elemento `input` e un singolo elemento `button`.
```js
assert(
Enzyme.mount(React.createElement(CheckUserAge)).find('div').find('input')
.length === 1 &&
Enzyme.mount(React.createElement(CheckUserAge)).find('div').find('button')
.length === 1
);
```
Lo stato del componente `CheckUserAge` dovrebbe essere inizializzato con una proprietà di `userAge` e una proprietà `input`, entrambe impostate sul valore di una stringa vuota.
```js
assert(
Enzyme.mount(React.createElement(CheckUserAge)).state().input === '' &&
Enzyme.mount(React.createElement(CheckUserAge)).state().userAge === ''
);
```
Quando il componente `CheckUserAge` viene presentato per la prima volta nel DOM, il testo interno del `button` dovrebbe essere Submit.
```js
assert(
Enzyme.mount(React.createElement(CheckUserAge)).find('button').text() ===
'Submit'
);
```
Quando viene inserito un numero inferiore a 18 nell'elemento `input` e viene cliccato il `button`, il testo all'interno del `button` dovrebbe essere `You Shall Not Pass`.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(CheckUserAge));
const initialButton = mockedComponent.find('button').text();
const enter3AndClickButton = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: '3' } });
mockedComponent.find('button').simulate('click');
mockedComponent.update();
return mockedComponent.find('button').text();
};
const enter17AndClickButton = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: '17' } });
mockedComponent.find('button').simulate('click');
mockedComponent.update();
return mockedComponent.find('button').text();
};
const userAge3 = enter3AndClickButton();
const userAge17 = enter17AndClickButton();
assert(
initialButton === 'Submit' &&
userAge3 === 'You Shall Not Pass' &&
userAge17 === 'You Shall Not Pass'
);
})();
```
Quando un numero maggiore o uguale a 18 viene inserito nell'elemento `input` e il `button` viene cliccato, il testo interno del `button` dovrebbe essere `You May Enter`.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(CheckUserAge));
const initialButton = mockedComponent.find('button').text();
const enter18AndClickButton = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: '18' } });
mockedComponent.find('button').simulate('click');
mockedComponent.update();
return mockedComponent.find('button').text();
};
const enter35AndClickButton = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: '35' } });
mockedComponent.find('button').simulate('click');
mockedComponent.update();
return mockedComponent.find('button').text();
};
const userAge18 = enter18AndClickButton();
const userAge35 = enter35AndClickButton();
assert(
initialButton === 'Submit' &&
userAge18 === 'You May Enter' &&
userAge35 === 'You May Enter'
);
})();
```
Una volta che un numero è stato inviato, e il valore dell'`input` è cambiato ancora una volta, il `button` dovrebbe tornare al testo `Submit`.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(CheckUserAge));
const enter18AndClickButton = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: '18' } });
mockedComponent.find('button').simulate('click');
mockedComponent.update();
return mockedComponent.find('button').text();
};
const changeInputDontClickButton = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: '5' } });
mockedComponent.update();
return mockedComponent.find('button').text();
};
const enter10AndClickButton = () => {
mockedComponent
.find('input')
.simulate('change', { target: { value: '10' } });
mockedComponent.find('button').simulate('click');
mockedComponent.update();
return mockedComponent.find('button').text();
};
const userAge18 = enter18AndClickButton();
const changeInput1 = changeInputDontClickButton();
const userAge10 = enter10AndClickButton();
const changeInput2 = changeInputDontClickButton();
assert(
userAge18 === 'You May Enter' &&
changeInput1 === 'Submit' &&
userAge10 === 'You Shall Not Pass' &&
changeInput2 === 'Submit'
);
})();
```
Il tuo codice non dovrebbe contenere alcuna istruzione `if/else`.
```js
assert(
new RegExp(/(\s|;)if(\s|\()/).test(
Enzyme.mount(React.createElement(CheckUserAge)).instance().render.toString()
) === false
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<CheckUserAge />, document.getElementById('root'));
```
## --seed-contents--
```jsx
const inputStyle = {
width: 235,
margin: 5
};
class CheckUserAge extends React.Component {
constructor(props) {
super(props);
// Change code below this line
// Change code above this line
this.submit = this.submit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({
input: e.target.value,
userAge: ''
});
}
submit() {
this.setState(state => ({
userAge: state.input
}));
}
render() {
const buttonOne = <button onClick={this.submit}>Submit</button>;
const buttonTwo = <button>You May Enter</button>;
const buttonThree = <button>You Shall Not Pass</button>;
return (
<div>
<h3>Enter Your Age to Continue</h3>
<input
style={inputStyle}
type='number'
value={this.state.input}
onChange={this.handleChange}
/>
<br />
{/* Change code below this line */}
{/* Change code above this line */}
</div>
);
}
}
```
# --solutions--
```jsx
const inputStyle = {
width: 235,
margin: 5
};
class CheckUserAge extends React.Component {
constructor(props) {
super(props);
this.state = {
userAge: '',
input: ''
};
this.submit = this.submit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({
input: e.target.value,
userAge: ''
});
}
submit() {
this.setState(state => ({
userAge: state.input
}));
}
render() {
const buttonOne = <button onClick={this.submit}>Submit</button>;
const buttonTwo = <button>You May Enter</button>;
const buttonThree = <button>You Shall Not Pass</button>;
return (
<div>
<h3>Enter Your Age to Continue</h3>
<input
style={inputStyle}
type='number'
value={this.state.input}
onChange={this.handleChange}
/>
<br />
{this.state.userAge === ''
? buttonOne
: this.state.userAge >= 18
? buttonTwo
: buttonThree}
</div>
);
}
}
```

View File

@ -0,0 +1,334 @@
---
id: 5a24c314108439a4d4036183
title: Usare JavaScript avanzato nel metodo Render di React
challengeType: 6
forumTopicId: 301415
dashedName: use-advanced-javascript-in-react-render-method
---
# --description--
Nelle sfide precedenti, hai imparato come iniettare il codice JavaScript nel codice JSX utilizzando le parentesi graffe, `{ }`, per attività come accedere alle props, passare props, accedere allo stato, inserire commenti nel codice e, più recentemente, stilizzare i componenti. Questi sono tutti casi in cui normalmente si inserisce del JavaScript in JSX, ma non sono l'unico modo in cui è possibile utilizzare il codice JavaScript nei componenti React.
Puoi anche scrivere JavaScript direttamente nei tuoi metodi `render`, prima dell'istruzione `return`, ***senza*** inserirlo all'interno delle parentesi graffe. Questo perché non è ancora all'interno del codice JSX. Quando successivamente vorrai utilizzare una variabile nel codice JSX *all'interno* dell'istruzione `return`, posizionerai il nome della variabile all'interno delle parentesi graffe.
# --instructions--
Nel codice fornito, il metodo `render` ha un array che contiene 20 frasi per rappresentare le risposte trovate nel classico giocattolo degli anni '80 Magica Palla Otto. L'evento click del bottone è associato al metodo `ask`, così ogni volta che il pulsante viene cliccato un numero casuale verrà generato e memorizzato come `randomIndex` nello stato. Alla riga 52, elimina la stringa `change me!` e riassegna la costante `answer` in modo che il tuo codice acceda casualmente ad un diverso indice dell'array `possibleAnswers` ogni volta che il componente si aggiorna. Infine, inserisci la costante `answer` all'interno dei tag `p`.
# --hints--
Il componente `MagicEightBall` dovrebbe esistere ed essere presentato nella pagina.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall)).find('MagicEightBall')
.length,
1
);
```
Il primo figlio di `MagicEightBall` dovrebbe essere un elemento `input`.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall))
.children()
.childAt(0)
.name(),
'input'
);
```
Il terzo figlio di `MagicEightBall` dovrebbe essere un elemento `button`.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall))
.children()
.childAt(2)
.name(),
'button'
);
```
Lo stato di `MagicEightBall` dovrebbe essere inizializzato con una proprietà `userInput` e una proprietà `randomIndex` entrambe impostate su un valore di una stringa vuota.
```js
assert(
Enzyme.mount(React.createElement(MagicEightBall)).state('randomIndex') ===
'' &&
Enzyme.mount(React.createElement(MagicEightBall)).state('userInput') === ''
);
```
Quando `MagicEightBall` viene montato per la prima volta sul DOM, dovrebbe restituire un elemento `p` vuoto.
```js
assert(
Enzyme.mount(React.createElement(MagicEightBall)).find('p').length === 1 &&
Enzyme.mount(React.createElement(MagicEightBall)).find('p').text() === ''
);
```
Quando il testo viene inserito nell'elemento `input` e il pulsante viene cliccato, il componente `MagicEightBall` dovrebbe restituire un elemento `p` che contiene un elemento casuale prendendolo dall'array `possibleAnswers`.
```js
(() => {
const comp = Enzyme.mount(React.createElement(MagicEightBall));
const simulate = () => {
comp.find('input').simulate('change', { target: { value: 'test?' } });
comp.find('button').simulate('click');
};
const result = () => comp.find('p').text();
const _1 = () => {
simulate();
return result();
};
const _2 = () => {
simulate();
return result();
};
const _3 = () => {
simulate();
return result();
};
const _4 = () => {
simulate();
return result();
};
const _5 = () => {
simulate();
return result();
};
const _6 = () => {
simulate();
return result();
};
const _7 = () => {
simulate();
return result();
};
const _8 = () => {
simulate();
return result();
};
const _9 = () => {
simulate();
return result();
};
const _10 = () => {
simulate();
return result();
};
const _1_val = _1();
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
const _5_val = _5();
const _6_val = _6();
const _7_val = _7();
const _8_val = _8();
const _9_val = _9();
const _10_val = _10();
const actualAnswers = [
_1_val,
_2_val,
_3_val,
_4_val,
_5_val,
_6_val,
_7_val,
_8_val,
_9_val,
_10_val
];
const hasIndex = actualAnswers.filter(
(answer, i) => possibleAnswers.indexOf(answer) !== -1
);
const notAllEqual = new Set(actualAnswers);
assert(notAllEqual.size > 1 && hasIndex.length === 10);
})();
```
# --seed--
## --after-user-code--
```jsx
var possibleAnswers = [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes, definitely',
'You may rely on it',
'As I see it, yes',
'Outlook good',
'Yes',
'Signs point to yes',
'Reply hazy try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
"Don't count on it",
'My reply is no',
'My sources say no',
'Outlook not so good',
'Very doubtful',
'Most likely'
];
ReactDOM.render(<MagicEightBall />, document.getElementById('root'));
```
## --seed-contents--
```jsx
const inputStyle = {
width: 235,
margin: 5
};
class MagicEightBall extends React.Component {
constructor(props) {
super(props);
this.state = {
userInput: '',
randomIndex: ''
};
this.ask = this.ask.bind(this);
this.handleChange = this.handleChange.bind(this);
}
ask() {
if (this.state.userInput) {
this.setState({
randomIndex: Math.floor(Math.random() * 20),
userInput: ''
});
}
}
handleChange(event) {
this.setState({
userInput: event.target.value
});
}
render() {
const possibleAnswers = [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes, definitely',
'You may rely on it',
'As I see it, yes',
'Outlook good',
'Yes',
'Signs point to yes',
'Reply hazy try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
"Don't count on it",
'My reply is no',
'My sources say no',
'Most likely',
'Outlook not so good',
'Very doubtful'
];
const answer = 'change me!'; // Change this line
return (
<div>
<input
type='text'
value={this.state.userInput}
onChange={this.handleChange}
style={inputStyle}
/>
<br />
<button onClick={this.ask}>Ask the Magic Eight Ball!</button>
<br />
<h3>Answer:</h3>
<p>
{/* Change code below this line */}
{/* Change code above this line */}
</p>
</div>
);
}
}
```
# --solutions--
```jsx
const inputStyle = {
width: 235,
margin: 5
};
class MagicEightBall extends React.Component {
constructor(props) {
super(props);
this.state = {
userInput: '',
randomIndex: ''
};
this.ask = this.ask.bind(this);
this.handleChange = this.handleChange.bind(this);
}
ask() {
if (this.state.userInput) {
this.setState({
randomIndex: Math.floor(Math.random() * 20),
userInput: ''
});
}
}
handleChange(event) {
this.setState({
userInput: event.target.value
});
}
render() {
const possibleAnswers = [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes, definitely',
'You may rely on it',
'As I see it, yes',
'Outlook good',
'Yes',
'Signs point to yes',
'Reply hazy try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
"Don't count on it",
'My reply is no',
'My sources say no',
'Outlook not so good',
'Very doubtful',
'Most likely'
];
const answer = possibleAnswers[this.state.randomIndex];
return (
<div>
<input
type='text'
value={this.state.userInput}
onChange={this.handleChange}
style={inputStyle}
/>
<br />
<button onClick={this.ask}>Ask the Magic Eight Ball!</button>
<br />
<h3>Answer:</h3>
<p>{answer}</p>
</div>
);
}
}
```

View File

@ -0,0 +1,236 @@
---
id: 5a24c314108439a4d403618c
title: Usare Array.filter() per filtrare dinamicamente un array
challengeType: 6
forumTopicId: 301416
dashedName: use-array-filter-to-dynamically-filter-an-array
---
# --description--
Il metodo degli array `map` è un potente strumento che userai spesso lavorando con React. Un altro metodo collegato a `map` è `filter`, che filtra il contenuto di un array in base a una condizione, restituendo un nuovo array. Ad esempio, se hai un array di utenti che hanno tutti una proprietà `online` che può essere impostata a `true` o `false`, puoi filtrare solo gli utenti che sono online scrivendo:
```js
let onlineUsers = users.filter(user => user.online);
```
# --instructions--
Nell'editor di codice, lo `state` di `MyComponent` è inizializzato con un array di utenti. Alcuni utenti sono online e altri no. Filtra l'array in modo da vedere solo gli utenti che sono online. Per fare questo, prima usa `filter` per restituire un nuovo array contenente solo gli utenti la cui proprietà `online` è `true`. Poi, nella variabile `renderOnline`, mappa l'array filtrato, e restituisci un elemento `li` contenente il testo dello `username` di ogni utente. Assicurati di includere anche una `key` unica, come nelle ultime sfide.
# --hints--
`MyComponent` dovrebbe esistere e essere presentato nellla pagina.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MyComponent)).find('MyComponent').length,
1
);
```
Lo stato di `MyComponent` dovrebbe essere inizializzato ad un array di sei utenti.
```js
assert(
Array.isArray(
Enzyme.mount(React.createElement(MyComponent)).state('users')
) === true &&
Enzyme.mount(React.createElement(MyComponent)).state('users').length === 6
);
```
`MyComponent` dovrebbe restituire un `div`, un `h1`, e poi una lista non ordinata contenente degli elementi `li` per ogni utente il cui stato online è impostato a `true`.
```js
(() => {
const comp = Enzyme.mount(React.createElement(MyComponent));
const users = (bool) => ({
users: [
{ username: 'Jeff', online: bool },
{ username: 'Alan', online: bool },
{ username: 'Mary', online: bool },
{ username: 'Jim', online: bool },
{ username: 'Laura', online: bool }
]
});
const result = () => comp.find('li').length;
const _1 = result();
const _2 = () => {
comp.setState(users(true));
return result();
};
const _3 = () => {
comp.setState(users(false));
return result();
};
const _4 = () => {
comp.setState({ users: [] });
return result();
};
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
assert(
comp.find('div').length === 1 &&
comp.find('h1').length === 1 &&
comp.find('ul').length === 1 &&
_1 === 4 &&
_2_val === 5 &&
_3_val === 0 &&
_4_val === 0
);
})();
```
`MyComponent` dovrebbe restituire gli elementi `li` che contengono lo `username` di ogni utente online.
```js
(() => {
const comp = Enzyme.mount(React.createElement(MyComponent));
const users = (bool) => ({
users: [
{ username: 'Jeff', online: bool },
{ username: 'Alan', online: bool },
{ username: 'Mary', online: bool },
{ username: 'Jim', online: bool },
{ username: 'Laura', online: bool }
]
});
const ul = () => {
comp.setState(users(true));
return comp.find('ul').html();
};
const html = ul();
assert(
html ===
'<ul><li>Jeff</li><li>Alan</li><li>Mary</li><li>Jim</li><li>Laura</li></ul>'
);
})();
```
Ogni elemento della lista dovrebbe avere un attributo `key` univoco.
```js
assert(
(() => {
const ul = Enzyme.mount(React.createElement(MyComponent)).find('ul');
console.log(ul.debug());
const keys = new Set([
ul.childAt(0).key(),
ul.childAt(1).key(),
ul.childAt(2).key(),
ul.childAt(3).key()
]);
return keys.size === 4;
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'));
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [
{
username: 'Jeff',
online: true
},
{
username: 'Alan',
online: false
},
{
username: 'Mary',
online: true
},
{
username: 'Jim',
online: false
},
{
username: 'Sara',
online: true
},
{
username: 'Laura',
online: true
}
]
};
}
render() {
const usersOnline = null; // Change this line
const renderOnline = null; // Change this line
return (
<div>
<h1>Current Online Users:</h1>
<ul>{renderOnline}</ul>
</div>
);
}
}
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [
{
username: 'Jeff',
online: true
},
{
username: 'Alan',
online: false
},
{
username: 'Mary',
online: true
},
{
username: 'Jim',
online: false
},
{
username: 'Sara',
online: true
},
{
username: 'Laura',
online: true
}
]
};
}
render() {
const usersOnline = this.state.users.filter(user => {
return user.online;
});
const renderOnline = usersOnline.map(user => {
return <li key={user.username}>{user.username}</li>;
});
return (
<div>
<h1>Current Online Users:</h1>
<ul>{renderOnline}</ul>
</div>
);
}
}
```

View File

@ -0,0 +1,265 @@
---
id: 5a24c314108439a4d403618a
title: Usare Array.map() per presentare dinamicamente gli elementi
challengeType: 6
forumTopicId: 301417
dashedName: use-array-map-to-dynamically-render-elements
---
# --description--
Il rendering condizionale è utile, ma potresti aver bisogno che i tuoi componenti presentino un numero sconosciuto di elementi. Spesso nella programmazione reattiva, un programmatore non ha modo di sapere qual è lo stato di un'applicazione fino al runtime, perché molto dipende dall'interazione di un utente con quel programma. I programmatori devono quindi scrivere il loro codice per gestire correttamente quello stato sconosciuto prima di conoscerlo. L'uso di `Array.map()` in React illustra questo concetto.
Creiamo ad esempio una semplice app "To Do List". Come programmatore, non hai modo di sapere quanti elementi un utente potrebbe avere nella sua lista. È necessario impostare il componente per presentare dinamicamente il numero corretto di elementi della lista molto prima che qualcuno che utilizza il programma decida che oggi è giorno di bucato.
# --instructions--
Nell'editor di codice troverai il componente `MyToDoList` quasi completamente configurato. Alcune parti di questo codice dovrebbero esserti familiari se hai completato la sfida del modulo controllato. Noterai una `textarea` e un `button`, insieme a un paio di metodi che tracciano i loro stati, ma per il momento niente è ancora presentato nella pagina.
All'interno del `constructor`, crea un oggetto `this.state` e definisci due stati: `userInput` dovrebbe essere inizializzato con una stringa vuota, e `toDoList` dovrebbe essere inizializzato con un array vuoto. Successivamente, elimina il commento nel metodo `render()` accanto alla variabile `items`. Al suo posto, mappa l'array `toDoList` memorizzato nello stato interno del componente e presenta dinamicamente un `li` per ogni elemento. Prova ad inserire la stringa `eat, code, sleep, repeat` nella `textarea`, quindi fai clic sul bottone per vedere cosa succede.
**Nota:** Forse sai già che tutti gli elementi figli (e fratelli tra loro) creati da un'operazione di mappatura come questa devono essere forniti con un attributo `key` univoco. Non ti preoccupare, questo è il tema della prossima sfida.
# --hints--
Il componente MyToDoList dovrebbe esistere ed essere presentato nella pagina.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyToDoList));
return mockedComponent.find('MyToDoList').length === 1;
})()
);
```
Il primo figlio di `MyToDoList` dovrebbe essere un elemento `textarea`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyToDoList));
return (
mockedComponent.find('MyToDoList').children().childAt(0).type() ===
'textarea'
);
})()
);
```
Il secondo figlio di `MyToDoList` dovrebbe essere un elemento `br`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyToDoList));
return (
mockedComponent.find('MyToDoList').children().childAt(1).type() === 'br'
);
})()
);
```
Il terzo figlio di `MyToDoList` dovrebbe essere un elemento `button`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyToDoList));
return (
mockedComponent.find('MyToDoList').children().childAt(2).type() ===
'button'
);
})()
);
```
Lo stato di `MyToDoList` dovrebbe essere inizializzato con `toDoList` come un array vuoto.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyToDoList));
const initialState = mockedComponent.state();
return (
Array.isArray(initialState.toDoList) === true &&
initialState.toDoList.length === 0
);
})()
);
```
Lo stato di `MyToDoList` dovrebbe essere inizializzato con `userInput` come una stringa vuota.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyToDoList));
const initialState = mockedComponent.state();
return (
typeof initialState.userInput === 'string' &&
initialState.userInput.length === 0
);
})()
);
```
Quando viene cliccato il bottone `Create List`, il componente `MyToDoList` dovrebbe restituire dinamicamente una lista non ordinata che contiene un li (list item) per ogni elemento di una lista separata da virgole inserito nell'elemento `textarea`.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyToDoList));
const simulateChange = (el, value) =>
el.simulate('change', { target: { value } });
const state_1 = () => {
return mockedComponent.find('ul').find('li');
};
const setInput = () => {
return simulateChange(
mockedComponent.find('textarea'),
'testA, testB, testC'
);
};
const click = () => {
return mockedComponent.find('button').simulate('click');
};
const state_2 = () => {
const nodes = mockedComponent.find('ul').find('li');
return { nodes, text: nodes.reduce((t, n) => t + n.text().trim(), '') };
};
const setInput_2 = () => {
return simulateChange(
mockedComponent.find('textarea'),
't1, t2, t3, t4, t5, t6'
);
};
const click_1 = () => {
return mockedComponent.find('button').simulate('click');
};
const state_3 = () => {
const nodes = mockedComponent.find('ul').find('li');
return { nodes, text: nodes.reduce((t, n) => t + n.text().trim(), '') };
};
const awaited_state_1 = state_1();
const awaited_setInput = setInput();
const awaited_click = click();
const awaited_state_2 = state_2();
const awaited_setInput_2 = setInput_2();
const awaited_click_1 = click_1();
const awaited_state_3 = state_3();
assert(
awaited_state_1.length === 0 &&
awaited_state_2.nodes.length === 3 &&
awaited_state_3.nodes.length === 6 &&
awaited_state_2.text === 'testAtestBtestC' &&
awaited_state_3.text === 't1t2t3t4t5t6'
);
})();
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyToDoList />, document.getElementById('root'));
```
## --seed-contents--
```jsx
const textAreaStyles = {
width: 235,
margin: 5
};
class MyToDoList extends React.Component {
constructor(props) {
super(props);
// Change code below this line
// Change code above this line
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleSubmit() {
const itemsArray = this.state.userInput.split(',');
this.setState({
toDoList: itemsArray
});
}
handleChange(e) {
this.setState({
userInput: e.target.value
});
}
render() {
const items = null; // Change this line
return (
<div>
<textarea
onChange={this.handleChange}
value={this.state.userInput}
style={textAreaStyles}
placeholder='Separate Items With Commas'
/>
<br />
<button onClick={this.handleSubmit}>Create List</button>
<h1>My "To Do" List:</h1>
<ul>{items}</ul>
</div>
);
}
}
```
# --solutions--
```jsx
const textAreaStyles = {
width: 235,
margin: 5
};
class MyToDoList extends React.Component {
constructor(props) {
super(props);
this.state = {
toDoList: [],
userInput: ''
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleSubmit() {
const itemsArray = this.state.userInput.split(',');
this.setState({
toDoList: itemsArray
});
}
handleChange(e) {
this.setState({
userInput: e.target.value
});
}
render() {
const items = this.state.toDoList.map((item, i) => {
return <li key={i}>{item}</li>;
});
return (
<div>
<textarea
onChange={this.handleChange}
value={this.state.userInput}
style={textAreaStyles}
placeholder='Separate Items With Commas'
/>
<br />
<button onClick={this.handleSubmit}>Create List</button>
<h1>My "To Do" List:</h1>
<ul>{items}</ul>
</div>
);
}
}
```

View File

@ -0,0 +1,78 @@
---
id: 5a24c314108439a4d403616b
title: Usare le proprietà predefinite
challengeType: 6
forumTopicId: 301418
dashedName: use-default-props
---
# --description--
React ha anche un'opzione per impostare props predefinite. È possibile assegnare props predefinite a un componente come una proprietà del componente stesso, in modo che React le assegni quando necessario. Questo ti permette di specificare quale valore dovrebbe avere una prop se nessun valore è esplicitamente fornito. Ad esempio, se dichiari `MyComponent.defaultProps = { location: 'San Francisco' }`, hai definito una prop location impostata sulla stringa `San Francisco`, a meno che non specifichi diversamente. React assegna le prop di default se non sono definite, ma se passi `null` come valore per una prop, essa rimarrà pari a `null`.
# --instructions--
L'editor di codice mostra un componente `ShoppingCart`. Definisci gli elementi predefiniti su questo componente in modo che specifichino una prop `items` con un valore di `0`.
# --hints--
Il componente `ShoppingCart` dovrebbe essere presentato.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ShoppingCart));
return mockedComponent.find('ShoppingCart').length === 1;
})()
);
```
Il componente `ShoppingCart` dovrebbe avere una prop predefinita di `{ items: 0 }`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ShoppingCart));
mockedComponent.setProps({ items: undefined });
return mockedComponent.find('ShoppingCart').props().items === 0;
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<ShoppingCart />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const ShoppingCart = (props) => {
return (
<div>
<h1>Shopping Cart Component</h1>
</div>
)
};
// Change code below this line
```
# --solutions--
```jsx
const ShoppingCart = (props) => {
return (
<div>
<h1>Shopping Cart Component</h1>
</div>
)
};
// Change code below this line
ShoppingCart.defaultProps = {
items: 0
}
```

View File

@ -0,0 +1,132 @@
---
id: 5a24c314108439a4d403616d
title: Usare i PropTypes per definire le Prop attese
challengeType: 6
forumTopicId: 301419
dashedName: use-proptypes-to-define-the-props-you-expect
---
# --description--
React fornisce utili funzioni di verifica del tipo per verificare che i componenti ricevano proprietà del tipo corretto. Ad esempio, la tua applicazione effettua una chiamata API per recuperare dei dati che ti aspetti essere in un array, che viene poi passato a un componente come proprietà. Puoi impostare `propTypes` sul tuo componente per richiedere che i dati siano di tipo `array`. Questo genera un avviso utile quando i dati saranno di qualsiasi altro tipo.
È considerata una buona pratica impostare `propTypes` quando si conosce il tipo di una prop in anticipo. Puoi definire una proprietà `propTypes` per un componente nello stesso modo in cui hai definito `defaultProps`. In questo modo verrà verificato che la prop con una data chiave sia presente con un dato tipo. Ecco un esempio per richiedere il tipo `function` per una prop chiamata `handleClick`:
```js
MyComponent.propTypes = { handleClick: PropTypes.func.isRequired }
```
Nell'esempio sopra, la parte `PropTypes.func` controlla che `handleClick` sia una funzione. Aggiungendo `isRequired` si dice a React che `handleClick` è una proprietà richiesta per quel componente. Se quella prop non è fornita vedrai un avviso. Nota anche che `func` rappresenta `function`. Tra i sette tipi primitivi JavaScript, `function` e `boolean` (scritto come `bool`) sono gli unici che usano un'ortografia insolita. Oltre ai tipi primitivi, ci sono altri tipi disponibili. Ad esempio, puoi controllare che una prop sia un elemento React. Fai riferimento alla [documentazione](https://reactjs.org/docs/jsx-in-depth.html#specifying-the-react-element-type) per tutte le opzioni.
**Nota:** A partire da React v15.5.0, `PropTypes` viene importato indipendentemente da React, in questo modo: `import PropTypes from 'prop-types';`
# --instructions--
Definisci `propTypes` in modo che il componente `Items` richieda `quantity` come prop e verifica che sia di tipo `number`.
# --hints--
Il componente `ShoppingCart` dovrebbe essere presentato.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ShoppingCart));
return mockedComponent.find('ShoppingCart').length === 1;
})()
);
```
Il componente `Items` dovrebbe essere presentato.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(ShoppingCart));
return mockedComponent.find('Items').length === 1;
})()
);
```
Il componente `Items` dovrebbe includere un controllo di `propTypes` per richiedere un valore per `quantity` e assicurarsi che il suo valore sia un numero.
```js
(getUserInput) =>
assert(
(function () {
const noWhiteSpace = __helpers.removeWhiteSpace(getUserInput('index'));
return (
noWhiteSpace.includes('quantity:PropTypes.number.isRequired') &&
noWhiteSpace.includes('Items.propTypes=')
);
})()
);
```
# --seed--
## --before-user-code--
```jsx
var PropTypes = {
number: { isRequired: true }
};
```
## --after-user-code--
```jsx
ReactDOM.render(<ShoppingCart />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const Items = (props) => {
return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
};
// Change code below this line
// Change code above this line
Items.defaultProps = {
quantity: 0
};
class ShoppingCart extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Items />
}
};
```
# --solutions--
```jsx
const Items = (props) => {
return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
};
// Change code below this line
Items.propTypes = {
quantity: PropTypes.number.isRequired
};
// Change code above this line
Items.defaultProps = {
quantity: 0
};
class ShoppingCart extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Items />
}
};
```

View File

@ -0,0 +1,150 @@
---
id: 5a24c314108439a4d4036165
title: Usare React per presentare i componenti annidati
challengeType: 6
forumTopicId: 301420
dashedName: use-react-to-render-nested-components
---
# --description--
L'ultima sfida ha mostrato un modo semplice per comporre due componenti, ma ci sono molti modi diversi per comporre componenti con React.
La composizione dei componenti è una delle potenti caratteristiche di React. Quando si lavora con React, è importante iniziare a pensare alla tua interfaccia utente in termini di componenti come abbiamo visto nell'App di esempio dell'ultima sfida. Scomponi la tua interfaccia utente nei suoi blocchi di base e quei pezzi diventeranno i componenti. Questo aiuta a separare il codice responsabile dell'interfaccia utente dal codice responsabile della gestione della logica dell'applicazione. Questo può semplificare notevolmente lo sviluppo e il mantenimento di progetti complessi.
# --instructions--
Ci sono due componenti funzionali definiti nell'editor di codice, chiamati `TypesOfFruit` e `Fruits`. Prendi il componente `TypesOfFruit` e componilo o *annidalo* all'interno del componente `Fruits`. Quindi prendi il componente `Fruits` e annidalo all'interno del componente `TypesOfFood`. Il risultato dovrebbe essere un componente figlio, annidato all'interno di un componente genitore, che è annidato all'interno di un componente genitore proprio!
# --hints--
Il componente `TypesOfFood` dovrebbe restituire un singolo elemento `div`.
```js
assert(Enzyme.shallow(React.createElement(TypesOfFood)).type() === 'div');
```
Il componente `TypesOfFood` dovrebbe restituire il componente `Fruits`.
```js
assert(
Enzyme.shallow(React.createElement(TypesOfFood)).props().children[1].type
.name === 'Fruits'
);
```
Il componente `Fruits` dovrebbe restituire il componente `TypesOfFruit`.
```js
assert(
Enzyme.mount(React.createElement(TypesOfFood)).find('h2').html() ===
'<h2>Fruits:</h2>'
);
```
Il componente `TypesOfFruit` dovrebbe restituire gli elementi `h2` e `ul`.
```js
assert(
Enzyme.mount(React.createElement(TypesOfFood)).find('ul').text() ===
'ApplesBlueberriesStrawberriesBananas'
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<TypesOfFood />, document.getElementById('root'))
```
## --seed-contents--
```jsx
const TypesOfFruit = () => {
return (
<div>
<h2>Fruits:</h2>
<ul>
<li>Apples</li>
<li>Blueberries</li>
<li>Strawberries</li>
<li>Bananas</li>
</ul>
</div>
);
};
const Fruits = () => {
return (
<div>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
};
class TypesOfFood extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>Types of Food:</h1>
{ /* Change code below this line */ }
{ /* Change code above this line */ }
</div>
);
}
};
```
# --solutions--
```jsx
const TypesOfFruit = () => {
return (
<div>
<h2>Fruits:</h2>
<ul>
<li>Apples</li>
<li>Blueberries</li>
<li>Strawberries</li>
<li>Bananas</li>
</ul>
</div>
);
};
const Fruits = () => {
return (
<div>
{ /* Change code below this line */ }
<TypesOfFruit />
{ /* Change code above this line */ }
</div>
);
};
class TypesOfFood extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>Types of Food:</h1>
{ /* Change code below this line */ }
<Fruits />
{ /* Change code above this line */ }
</div>
);
}
};
```

View File

@ -0,0 +1,189 @@
---
id: 5a24c314108439a4d4036176
title: Usare lo stato per attivare e disattivare un elemento
challengeType: 6
forumTopicId: 301421
dashedName: use-state-to-toggle-an-element
---
# --description--
A volte potrebbe essere necessario conoscere lo stato precedente quando si aggiorna lo stato. Tuttavia, gli aggiornamenti dello stato possono essere asincroni - questo significa che React può raggruppare più chiamate `setState()` in un singolo aggiornamento. Questo significa che non puoi fare affidamento sul valore precedente di `this.state` o di `this.props` quando calcoli il valore successivo. Quindi, non si dovrebbe utilizzare il codice in questo modo:
```jsx
this.setState({
counter: this.state.counter + this.props.increment
});
```
Invece, dovresti passare a `setState` una funzione che ti permetta di accedere a stato e props. L'utilizzo di una funzione con `setState` garantisce che si sta lavorando con i valori più aggiornati di stato e props. Questo significa che quanto sopra dovrebbe essere riscritto come:
```jsx
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
Puoi anche usare una forma senza `props` se hai bisogno solo dello `state`:
```jsx
this.setState(state => ({
counter: state.counter + 1
}));
```
Nota che devi avvolgere l'oggetto letterale tra parentesi, altrimenti JavaScript pensa che sia un blocco di codice.
# --instructions--
`MyComponent` ha una proprietà `visibility` che viene inizializzata a `false`. Il metodo render restituisce una vista se il valore di `visibility` è true, e una vista diversa se è false.
Attualmente, non c'è modo di aggiornare la proprietà `visibility` nello `state` del componente. Il valore dovrebbe commutare avanti e indietro tra vero e falso. C'è un gestore di click sul bottone che attiva un metodo di classe chiamato `toggleVisibility()`. Passa una funzione a `setState` per definire questo metodo in modo che lo `state` di `visibility` commuti al valore opposto quando viene chiamato il metodo. Se `visibility` è `false`, il metodo lo imposta a `true`, e viceversa.
Infine, fai click sul pulsante per vedere il rendering condizionale del componente in base al suo `state`.
**Suggerimento:** Non dimenticare di associare la parola chiave `this` al metodo nel `constructor`!
# --hints--
`MyComponent` dovrebbe restituire un elemento `div` che contiene un `button`.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MyComponent)).find('div').find('button')
.length,
1
);
```
Lo stato di `MyComponent` dovrebbe essere inizializzato con una proprietà `visibility` impostata su `false`.
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MyComponent)).state('visibility'),
false
);
```
Cliccando sul bottone si dovrebbe commutare la proprietà `visibility` nello stato, tra i due valori `true` e `false`.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const first = () => {
mockedComponent.setState({ visibility: false });
return mockedComponent.state('visibility');
};
const second = () => {
mockedComponent.find('button').simulate('click');
return mockedComponent.state('visibility');
};
const third = () => {
mockedComponent.find('button').simulate('click');
return mockedComponent.state('visibility');
};
const firstValue = first();
const secondValue = second();
const thirdValue = third();
assert(!firstValue && secondValue && !thirdValue);
})();
```
Una funzione anonima dovrebbe essere passata a `setState`.
```js
const paramRegex = '[a-zA-Z$_]\\w*(,[a-zA-Z$_]\\w*)?';
assert(
new RegExp(
'this\\.setState\\((function\\(' +
paramRegex +
'\\){|([a-zA-Z$_]\\w*|\\(' +
paramRegex +
'\\))=>)'
).test(__helpers.removeWhiteSpace(code))
);
```
`this` non dovrebbe essere usato all'interno di `setState`
```js
assert(!/this\.setState\([^}]*this/.test(code));
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'));
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
visibility: false
};
// Change code below this line
// Change code above this line
}
// Change code below this line
// Change code above this line
render() {
if (this.state.visibility) {
return (
<div>
<button onClick={this.toggleVisibility}>Click Me</button>
<h1>Now you see me!</h1>
</div>
);
} else {
return (
<div>
<button onClick={this.toggleVisibility}>Click Me</button>
</div>
);
}
}
}
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
visibility: false
};
this.toggleVisibility = this.toggleVisibility.bind(this);
}
toggleVisibility() {
this.setState(state => ({
visibility: !state.visibility
}));
}
render() {
if (this.state.visibility) {
return (
<div>
<button onClick={this.toggleVisibility}>Click Me</button>
<h1>Now you see me!</h1>
</div>
);
} else {
return (
<div>
<button onClick={this.toggleVisibility}>Click Me</button>
</div>
);
}
}
}
```

View File

@ -0,0 +1,127 @@
---
id: 5a24c314108439a4d403617d
title: Usare il metodo del ciclo di vita componentDidMount
challengeType: 6
forumTopicId: 301422
dashedName: use-the-lifecycle-method-componentdidmount
---
# --description--
La maggior parte degli sviluppatori web, a un certo punto, deve chiamare un'API endpoint per recuperare i dati. Se stai lavorando con React, è importante sapere dove eseguire questa azione.
La migliore pratica con React è quella di effettuare chiamate API o qualsiasi chiamata al server nel metodo del ciclo di vita `componentDidMount()`. Questo metodo viene chiamato dopo che un componente è stato montato nel DOM. Qualsiasi chiamata a `setState()` qui attiverà un re-rendering del tuo componente. Quando chiami un'API in questo metodo, e imposti il tuo stato con i dati che l'API restituisce, si attiverà automaticamente un aggiornamento una volta che i dati saranno ricevuti.
# --instructions--
C'è una chiamata API finta in `componentDidMount()`. Essa imposta lo stato dopo 2.5 secondi per simulare la chiamata a un server per recuperare i dati. Questo esempio richiede il numero di utenti attivi per un sito. Nel metodo render, presenta il valore di `activeUsers` nell'`h1` dopo il testo `Active Users:`. Guarda cosa succede nell'anteprima e sentiti libero di cambiare il timeout per vedere i diversi effetti.
# --hints--
`MyComponent` dovrebbe mostrare un elemento `div` che contiene un tag `h1`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return (
mockedComponent.find('div').length === 1 &&
mockedComponent.find('h1').length === 1
);
})()
);
```
Lo stato del componente dovrebbe essere aggiornato con una funzione timeout in `componentDidMount`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return new RegExp('setTimeout(.|\n)+setState(.|\n)+activeUsers').test(
String(mockedComponent.instance().componentDidMount)
);
})()
);
```
Il tag `h1` dovrebbe presentare il valore `activeUsers` dallo stato di `MyComponent`.
```js
(() => {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
const first = () => {
mockedComponent.setState({ activeUsers: 1237 });
return mockedComponent.find('h1').text();
};
const second = () => {
mockedComponent.setState({ activeUsers: 1000 });
return mockedComponent.find('h1').text();
};
assert(new RegExp('1237').test(first()) && new RegExp('1000').test(second()));
})();
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'));
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
activeUsers: null
};
}
componentDidMount() {
setTimeout(() => {
this.setState({
activeUsers: 1273
});
}, 2500);
}
render() {
return (
<div>
{/* Change code below this line */}
<h1>Active Users: </h1>
{/* Change code above this line */}
</div>
);
}
}
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
activeUsers: null
};
}
componentDidMount() {
setTimeout(() => {
this.setState({
activeUsers: 1273
});
}, 2500);
}
render() {
return (
<div>
<h1>Active Users: {this.state.activeUsers}</h1>
</div>
);
}
}
```

View File

@ -0,0 +1,87 @@
---
id: 5a24c314108439a4d403617c
title: Usare il metodo del ciclo di vita componentWillMount
challengeType: 6
forumTopicId: 301423
dashedName: use-the-lifecycle-method-componentwillmount
---
# --description--
I componenti React hanno diversi metodi speciali che offrono l'opportunità di eseguire azioni in punti specifici del ciclo di vita di un componente. Questi sono chiamati metodi del ciclo di vita, o hooks (ganci) del ciclo di vita, e consentono di intercettare i componenti in determinati istanti. Ad esempio prima che sia fatto il render del componente, prima di aggiornarlo, prima di ricevere le prop, prima di smontarlo, e così via. Ecco un elenco di alcuni dei principali metodi del ciclo di vita: `componentWillMount()` `componentDidMount()` `shouldComponentUpdate()` `componentDidUpdate()` `componentWillUnmount()` Le prossime lezioni copriranno alcuni dei casi di base per questi metodi del ciclo di vita.
**Nota:** Il metodo del ciclo di vita `componentWillMount` sarà deprecato in una versione futura di 16.X e rimosso nella versione 17. [(Fonte)](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html)
# --instructions--
Il metodo `componentWillMount()` viene chiamato prima del metodo `render()` quando un componente viene montato sul DOM. Scrivi qualcosa nella console all'interno di `componentWillMount()` - potresti aprire la console del browser per vedere l'output.
# --hints--
`MyComponent` dovrebbe presentare un elemento `div`.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.find('div').length === 1;
})()
);
```
`console.log` dovrebbe essere chiamato in `componentWillMount`.
```js
assert(
(function () {
const lifecycle = React.createElement(MyComponent)
.type.prototype.componentWillMount.toString()
.replace(/ /g, '');
return lifecycle.includes('console.log(');
})()
);
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<MyComponent />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
componentWillMount() {
// Change code below this line
// Change code above this line
}
render() {
return <div />
}
};
```
# --solutions--
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
componentWillMount() {
// Change code below this line
console.log('Component is mounting...');
// Change code above this line
}
render() {
return <div />
}
};
```

View File

@ -0,0 +1,84 @@
---
id: 5a24c314108439a4d4036168
title: Scrivere un componente React da zero
challengeType: 6
forumTopicId: 301424
dashedName: write-a-react-component-from-scratch
---
# --description--
Ora che hai imparato le basi dei componenti JSX e React, è il momento di scrivere un componente da solo. I componenti di React sono gli elementi fondamentali delle applicazioni React quindi è importante acquisire familiarità con la loro scrittura. Ricorda, un componente React tipico è una `class` ES6 che estende `React.Component`. Essa ha un metodo render che restituisce HTML (da JSX) o `null`. Questa è la forma di base di una componente React. Una volta che avrai capito bene questo, sarai pronto a iniziare a costruire progetti React più complessi.
# --instructions--
Definisci una classe `MyComponent` che estenda `React.Component`. Il suo metodo render dovrebbe restituire un `div` che contiene un tag `h1` con il testo: `My First React Component!` in esso. Usa questo testo esattamente, le maiuscole e la punteggiatura contano. Assicurati di chiamare anche il costruttore per il tuo componente.
Presenta questo componente nel DOM usando `ReactDOM.render()`. C'è un `div` con `id='challenge-node'` pronto all'uso per te.
# --hints--
Ci dovrebbe essere un componente React chiamato `MyComponent`.
```js
(getUserInput) =>
assert(
__helpers
.removeWhiteSpace(getUserInput('index'))
.includes('classMyComponentextendsReact.Component{')
);
```
`MyComponent` dovrebbe contenere un tag `h1` con testo `My First React Component!` Maiuscole e punteggiatura contano.
```js
assert(
(function () {
const mockedComponent = Enzyme.mount(React.createElement(MyComponent));
return mockedComponent.find('h1').text() === 'My First React Component!';
})()
);
```
`MyComponent` dovrebbe essere presentato nel DOM.
```js
assert(document.getElementById('challenge-node').childNodes.length === 1);
```
`MyComponent` dovrebbe avere un costruttore che chiama `super` con `props`.
```js
assert(
MyComponent.toString().includes('MyComponent(props)') &&
MyComponent.toString().includes('_super.call(this, props)')
);
```
# --seed--
## --seed-contents--
```jsx
// Change code below this line
```
# --solutions--
```jsx
// Change code below this line
class MyComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h1>My First React Component!</h1>
</div>
);
}
};
ReactDOM.render(<MyComponent />, document.getElementById('challenge-node'));
```

View File

@ -0,0 +1,146 @@
---
id: 5a24c314108439a4d4036177
title: Scrivere un semplice contatore
challengeType: 6
forumTopicId: 301425
dashedName: write-a-simple-counter
---
# --description--
È possibile progettare un componente stateful più complesso combinando i concetti visti finora. Questi includono l'inizializzazione dello `state`, la scrittura di metodi che impostano lo `state` e l'assegnazione di gestori di click per attivare questi metodi.
# --instructions--
Il componente `Counter` tiene traccia di un valore `count` nello `state`. Ci sono due bottoni che chiamano i metodi `increment()` e `decrement()`. Scrivi questi metodi in modo che il valore del contatore venga incrementato o decrementato di 1 quando viene fatto click sul bottone appropriato. Inoltre, crea un metodo `reset()` in modo che quando si clicca il pulsante reset, il conteggio venga impostato a 0.
**Nota:** Assicurati di non modificare le `className` dei bottoni. Inoltre, ricordati di aggiungere i legami (bindings) necessari ai metodi appena creati nel costruttore.
# --hints--
`Counter` dovrebbe restituire un elemento `div` che contiene tre pulsanti con contenuto di testo nell'ordine: `Increment!`, `Decrement!`, `Reset`.
```js
assert(
(() => {
const mockedComponent = Enzyme.mount(React.createElement(Counter));
return (
mockedComponent.find('.inc').text() === 'Increment!' &&
mockedComponent.find('.dec').text() === 'Decrement!' &&
mockedComponent.find('.reset').text() === 'Reset'
);
})()
);
```
Lo stato di `Counter` dovrebbe essere inizializzato con una proprietà `count` impostata a `0`.
```js
const mockedComponent = Enzyme.mount(React.createElement(Counter));
assert(mockedComponent.find('h1').text() === 'Current Count: 0');
```
Cliccando sul bottone di incremento il conteggio dovrebbe aumentare di `1`.
```js
const mockedComponent = Enzyme.mount(React.createElement(Counter));
mockedComponent.find('.inc').simulate('click');
assert(mockedComponent.find('h1').text() === 'Current Count: 1');
```
Cliccando sul bottone di decremento il conteggio dovrebbe diminuire di `1`.
```js
const mockedComponent = Enzyme.mount(React.createElement(Counter));
mockedComponent.find('.dec').simulate('click');
assert(mockedComponent.find('h1').text() === 'Current Count: -1');
```
Cliccando sul bottone di reset il conteggio dovrebbe essere reimpostato a `0`.
```js
const mockedComponent = Enzyme.mount(React.createElement(Counter));
mockedComponent.setState({ count: 5 });
const currentCountElement = mockedComponent.find('h1');
assert(currentCountElement.text() === 'Current Count: 5');
mockedComponent.find('.reset').simulate('click');
assert(currentCountElement.text() === 'Current Count: 0');
```
# --seed--
## --after-user-code--
```jsx
ReactDOM.render(<Counter />, document.getElementById('root'))
```
## --seed-contents--
```jsx
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
// Change code below this line
// Change code above this line
}
// Change code below this line
// Change code above this line
render() {
return (
<div>
<button className='inc' onClick={this.increment}>Increment!</button>
<button className='dec' onClick={this.decrement}>Decrement!</button>
<button className='reset' onClick={this.reset}>Reset</button>
<h1>Current Count: {this.state.count}</h1>
</div>
);
}
};
```
# --solutions--
```jsx
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
this.reset = this.reset.bind(this);
}
reset() {
this.setState({
count: 0
});
}
increment() {
this.setState(state => ({
count: state.count + 1
}));
}
decrement() {
this.setState(state => ({
count: state.count - 1
}));
}
render() {
return (
<div>
<button className='inc' onClick={this.increment}>Increment!</button>
<button className='dec' onClick={this.decrement}>Decrement!</button>
<button className='reset' onClick={this.reset}>Reset</button>
<h1>Current Count: {this.state.count}</h1>
</div>
);
}
};
```