diff --git a/cypress/downloads/downloads.html b/cypress/downloads/downloads.html new file mode 100644 index 000000000..8a341e1b4 Binary files /dev/null and b/cypress/downloads/downloads.html differ diff --git a/src/components/Counter.js b/src/components/Counter.js index 447a5e849..e2595edcc 100644 --- a/src/components/Counter.js +++ b/src/components/Counter.js @@ -46,32 +46,37 @@ STEP 6: This click handler needs to use 'setCount' to set the 'count' to be zero again. */ +import { useState } from "react"; import React from 'react'; /* STEP 0 */ export default function Counter() { /* STEP 1 */ + let [count, setCount] = useState(0); const increment = () => { /* STEP 4 */ + setCount(count+1) }; const decrement = () => { /* STEP 5 */ + setCount(count-1) }; const reset = () => { - /* STEP 6 */ + setCount(count = 0) }; const style = { fontSize: '1.5em', marginBottom: '0.3em', - color: 'royalblue', /* STEP 2 */ + color: count%2 === 0 ? 'royalblue' : 'crimson', /* STEP 2 */ }; + return (

Counter

- Number 0 is even {/* STEP 3 */} + {count%2 ===0?

Number {count} is even

:

Number {count} is odd

} {/* STEP 3 */}
diff --git a/src/components/Input.js b/src/components/Input.js index 36bf8fe03..65ba747f8 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -34,34 +34,38 @@ STEP 6: We need to add an extra prop to the element like so: value={inputValue} */ -import React from 'react'; /* STEP 0 */ +import React , {useState} from 'react'; /* STEP 0 */ export default function Input() { /* STEP 1 */ - +const [inputValue, setInputValue] = useState("") const changeInput = evt => { // When the input changes, its whole value can be found inside the event object. // Log out the synthetic event object 'evt' and see for yourself. const { value } = evt.target; - + setInputValue(value) /* STEP 4 */ }; const reset = () => { + setInputValue("") /* STEP 5 */ }; const style = { fontSize: '1.5em', marginBottom: '0.3em', - color: 'royalblue', /* STEP 2 */ + color: inputValue.length > 10 ? "crimson" : "royalblue", /* STEP 2 */ }; + return (

Input

-
{/* STEP 3 */} +
+ {inputValue.toUpperCase()} +
{/* STEP 3 */}
- {/* STEP 6 */} + {/* STEP 6 */}
diff --git a/src/components/Moods.js b/src/components/Moods.js index 98b49467f..e09813381 100644 --- a/src/components/Moods.js +++ b/src/components/Moods.js @@ -28,7 +28,7 @@ STEPS 4, 5, 6: Inside these click handlers set the correct mood, using 'setMood' and the variables below the imports. */ -import React from 'react'; /* STEP 0 */ +import React, {useState} from 'react'; /* STEP 0 */ const initialMood = 'Not sure how I feel'; const happyMood = 'Quite happy!'; @@ -36,27 +36,32 @@ const sadMood = 'Rather sad'; export default function Moods() { /* STEP 1 */ - +const [mood, setMood] = useState(initialMood) + const makeHappy = () => { + setMood(happyMood) + /* STEP 4 */ }; const makeSad = () => { + setMood(sadMood) /* STEP 5 */ }; const reset = () => { /* STEP 6 */ + setMood(initialMood) }; const style = { fontSize: '1.5em', marginBottom: '0.3em', - color: 'crimson', /* STEP 2 */ + color: mood === happyMood ? "royalblue" : 'crimson', /* STEP 2 */ }; return (

Moods

-
Not sure how I feel
{/* STEP 3 */} +
{mood}
{/* STEP 3 */}
diff --git a/src/components/Programmers.js b/src/components/Programmers.js index bb4aee6bd..939318100 100644 --- a/src/components/Programmers.js +++ b/src/components/Programmers.js @@ -11,7 +11,7 @@ We can only feature one awesome programmer at a time. Find comments below to help you along. */ -import React from 'react'; +import React, {useState} from 'react'; // Use this variable ONLY to initialize a slice of state! // There is something in the JSX right now breaking this rule... @@ -28,8 +28,16 @@ export const listOfAwesome = [ export default function Programmers() { // We'll have to use the state hook twice, as we need two slices of state. // The programmers list on the one hand, and the id of the featured programmer on the other. - + const [programmers, setProgrammers] = useState(listOfAwesome) + const [featured, setFeatured]= useState(null) const getNameOfFeatured = () => { + + // for (let i = 0 ; i < programmers.length; i++){ + // if(programmers.id === featured){ + // return programmers[i].name + // + const foundDev = programmers.find(dev => dev.id ===featured) + return foundDev.name // Leave this for last! // This is NOT an event handler but a helper function. See its usage inside the JSX. // It's going to utilize both slices of state to return the _name_ of the featured dev. @@ -40,7 +48,7 @@ export default function Programmers() { const style = { fontSize: '1.5em', marginTop: '0.5em', - color: 'royalblue', // 🤔 color turns to gold, when celebrating + color: featured ? "gold" : 'royalblue', // 🤔 color turns to gold, when celebrating }; return ( @@ -51,21 +59,21 @@ export default function Programmers() { /* Nasty bug! We should map over a slice of state, instead of 'listOfAwesome'. We might think: "it works, though!" But if the list of programmers is not state, we could never add or edit programmers in the future. The list would be a static thing." */ - listOfAwesome.map(dev => + programmers.map(dev =>
- {dev.name} + {dev.name}
) }
diff --git a/src/components/Spinner.js b/src/components/Spinner.js index d0326fd34..d0d656d00 100644 --- a/src/components/Spinner.js +++ b/src/components/Spinner.js @@ -37,23 +37,24 @@ STEP 4: Do you remember the operator we use to do "not"? */ -import React from 'react'; /* STEP 0 */ +import React,{useState} from 'react'; /* STEP 0 */ export default function Spinner() { /* STEP 1 */ - +const [spinnerOn, setSpinnerOn] = useState(true) const toggleSpinner = () => { /* STEP 4 */ + {spinnerOn === true ? setSpinnerOn(false) : setSpinnerOn(true)} }; return (

Spinner

{ - true &&
--+--
/* STEP 2 */ + spinnerOn &&
--+--
/* STEP 2 */ }
); diff --git a/src/components/Squares.js b/src/components/Squares.js index 25ab72546..933610044 100644 --- a/src/components/Squares.js +++ b/src/components/Squares.js @@ -14,30 +14,35 @@ Only one square (or none) can be active at any given point. Find comments below to help you along. */ -import React from 'react'; +import React , {useState} from 'react'; // Use this variable ONLY to initialize a slice of state! const listOfSquareIds = ['sqA', 'sqB', 'sqC', 'sqD']; export default function Squares() { +const [squares, setSquares] = useState(listOfSquareIds) +const [activeSquares, setActiveSquares] = useState(null) // Use the state hook twice, as we need two slices of state: 'squares' and // 'activeSquare'. One holds the _array_ of square ids, and the other keeps track // of the currently active square. On page load there's no active square, // so the value of 'activeSquare' should be null. const getClassName = id => { + // This is NOT a click handler but a helper, used inside the JSX (see below). // It should return a string containing the class name of 'active', if the id passed // as the argument matches the active square in state, empty string otherwise. // Right-click and "inspect element" on the square to see its effect. - return '' + return id === activeSquares ? "active" : "" }; const markActive = id => { + // This is a helper used inside an _inlined_ click handler (see below). // Set the id argument to become the active id in state // (unless it already is, in which case we should reset // the currently active square id back to initial state). + id === activeSquares ? setActiveSquares(null) : setActiveSquares(id) }; return ( @@ -48,7 +53,7 @@ export default function Squares() { // Nasty bug! We should map over a slice of state, instead of 'listOfSquareIds'. // We might say: "it works, though!" But if the list of squares is not state, // we could never add squares, change squares or remove squares in the future. Fix! - listOfSquareIds.map(id => + squares.map(id =>