From 7fd34ff8b556ece09d3b1ee2141ec2251fbd02fb Mon Sep 17 00:00:00 2001 From: Gage Clancy Date: Mon, 21 Mar 2022 16:16:18 -0500 Subject: [PATCH 1/5] got the counter working --- src/components/Counter.js | 45 +++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/components/Counter.js b/src/components/Counter.js index 447a5e849..f36776316 100644 --- a/src/components/Counter.js +++ b/src/components/Counter.js @@ -18,19 +18,9 @@ The other things can simply be _derived_ from the count itself. STEP 0: Start by studying the component below, and importing the state hook. -STEP 1: - Using the state hook, create a 'count', 'setCount' pair. - The 'count' state should be initialized to the number zero. -STEP 2: - The 'style' object has the 'color' property hard-coded to "royalblue". - What the value of 'color' should be instead is a ternary expression that goes like this: - If count is even, then "royalblue", else "crimson". -STEP 3: - We need to replace some hard-coded info in the JSX with expressions, interpolated inside curly brackets. - Start by replacing the character "0" with {count}. The 'count' slice of state is the source of truth here. - Then, replace the word "even" with a ternary: {if count is even number, then string "even", else string "odd"}. + STEP 4: This click handler needs to use 'setCount' to schedule the 'count' to become the current 'count' plus one. @@ -46,32 +36,51 @@ STEP 6: This click handler needs to use 'setCount' to set the 'count' to be zero again. */ -import React from 'react'; /* STEP 0 */ +import React, { useState } from 'react'; /* STEP 0 */ export default function Counter() { - /* STEP 1 */ + // STEP 1: + // Using the state hook, create a 'count', 'setCount' pair. + // The 'count' state should be initialized to the number zero. + const [count, setCount] = useState(0); + const increment = () => { - /* STEP 4 */ + setCount(count + 1); }; const decrement = () => { - /* STEP 5 */ + setCount(count -1); }; const reset = () => { - /* STEP 6 */ + setCount(0); }; +function isEven(num) { + return num % 2; +}; + const style = { fontSize: '1.5em', marginBottom: '0.3em', - color: 'royalblue', /* STEP 2 */ + color: isEven(count) ? 'crimson' : 'royalblue', }; + /* STEP 2: + The 'style' object has the 'color' property hard-coded to "royalblue". + What the value of 'color' should be instead is a ternary expression that goes like this: + If count is even, then "royalblue", else "crimson". + */ + + // STEP 3: + // We need to replace some hard-coded info in the JSX with expressions, interpolated inside curly brackets. + // Start by replacing the character "0" with {count}. The 'count' slice of state is the source of truth here. + // Then, replace the word "even" with a ternary: {if count is even number, then string "even", else string "odd"}. + return (

Counter

- Number 0 is even {/* STEP 3 */} + Number {count} is {isEven(count) ? 'odd' : 'even'}
From aedc31357955f928240ac67d513a0e8f06c50e7a Mon Sep 17 00:00:00 2001 From: Gage Clancy Date: Mon, 21 Mar 2022 16:33:42 -0500 Subject: [PATCH 2/5] got the input working --- src/components/Input.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/Input.js b/src/components/Input.js index 36bf8fe03..7ccc21c96 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -34,34 +34,36 @@ 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 = () => { - /* STEP 5 */ + setInputValue(''); }; 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 */}
From e2bbb97db33dc6a1f680f8e7bc3eccaeaa50c33d Mon Sep 17 00:00:00 2001 From: Gage Clancy Date: Mon, 21 Mar 2022 16:44:57 -0500 Subject: [PATCH 3/5] got the moods working --- src/components/Moods.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/Moods.js b/src/components/Moods.js index 98b49467f..69945ee43 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,27 @@ const sadMood = 'Rather sad'; export default function Moods() { /* STEP 1 */ - + const [mood, setMood] = useState(initialMood); const makeHappy = () => { - /* STEP 4 */ + setMood(happyMood); }; const makeSad = () => { - /* STEP 5 */ + setMood(sadMood); }; 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 */}
From cf9dbc7c5947d40d25544d5ed85b7ea61115d8d1 Mon Sep 17 00:00:00 2001 From: Gage Clancy Date: Mon, 21 Mar 2022 20:12:51 -0500 Subject: [PATCH 4/5] squares done --- src/components/Programmers.js | 10 +++++++--- src/components/Spinner.js | 13 +++++++------ src/components/Squares.js | 10 ++++++++-- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/components/Programmers.js b/src/components/Programmers.js index e34c4f392..3491cccbb 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... @@ -23,10 +23,11 @@ export const listOfAwesome = [ { id: '5', name: 'Frances Allen' }, { id: '6', name: 'Carol Shaw' }, ]; - 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 [programmer, setProgrammer] = useState(0); + const [programmerName, setProgrammerName] = useState(''); const getNameOfFeatured = () => { // Leave this for last! @@ -34,6 +35,7 @@ export default function Programmers() { // It's going to utilize both slices of state to return the _name_ of the featured dev. // The beauty of closures is that we can "see" both slices of state from this region // of the program, without needing to inject the information through arguments. + }; const style = { @@ -52,7 +54,9 @@ export default function Programmers() { we could never add or edit programmers in the future. The list would be a static thing." */ listOfAwesome.map(dev =>
- {dev.name} + {dev.name}
) } diff --git a/src/components/Spinner.js b/src/components/Spinner.js index d0326fd34..08973d3e5 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 === false ? setSpinnerOn(true) : setSpinnerOn(false); + }; - + const spinnerText = spinnerOn===true ? 'Hide' : 'Show'; return (

Spinner

{ - true &&
--+--
/* STEP 2 */ + spinnerOn &&
--+--
/* STEP 2 */ }
); diff --git a/src/components/Squares.js b/src/components/Squares.js index 25ab72546..a15943c51 100644 --- a/src/components/Squares.js +++ b/src/components/Squares.js @@ -14,7 +14,7 @@ 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']; @@ -24,20 +24,26 @@ export default function Squares() { // '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 squares = useState(listOfSquareIds); +const [activeSquare, setActiveSquare] = useState(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 === activeSquare ? '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). + return activeSquare === id ? setActiveSquare(null) : setActiveSquare(id) ; }; return ( From bd41be6f4aae24e635963ed185048ea70d04e2cc Mon Sep 17 00:00:00 2001 From: Gage Clancy Date: Mon, 21 Mar 2022 21:10:13 -0500 Subject: [PATCH 5/5] done --- src/components/Programmers.js | 18 ++++++++---------- src/components/Squares.js | 4 ++-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/components/Programmers.js b/src/components/Programmers.js index 3491cccbb..7c975003d 100644 --- a/src/components/Programmers.js +++ b/src/components/Programmers.js @@ -26,22 +26,23 @@ 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 [programmer, setProgrammer] = useState(0); - const [programmerName, setProgrammerName] = useState(''); - + const [programmers, setProgrammers] = useState(listOfAwesome); + const [programmerId, setProgrammerId] = useState(null); + const getNameOfFeatured = () => { // 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. // The beauty of closures is that we can "see" both slices of state from this region // of the program, without needing to inject the information through arguments. + return programmers[programmerId-1].name; }; const style = { fontSize: '1.5em', marginTop: '0.5em', - color: 'royalblue', // 🤔 color turns to gold, when celebrating + color: programmerId ? "gold" : 'royalblue', // 🤔 color turns to gold, when celebrating }; return ( @@ -49,13 +50,10 @@ export default function Programmers() {

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}
) @@ -66,7 +64,7 @@ export default function Programmers() { // Ternaries are fantastic to render "one thing or the other" depending on the "truthiness" of something. // Pseudo-code: if the currently featured id is truthy render text 1, otherwise render text 2. // Replace the hard-coded false with the correct variable. - false + programmerId ? `🎉 Let's celebrate ${getNameOfFeatured()}! 🥳` : 'Pick an awesome programmer' } diff --git a/src/components/Squares.js b/src/components/Squares.js index a15943c51..f29060264 100644 --- a/src/components/Squares.js +++ b/src/components/Squares.js @@ -24,7 +24,7 @@ export default function Squares() { // '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 squares = useState(listOfSquareIds); +const [squares, setSquares] = useState(listOfSquareIds); const [activeSquare, setActiveSquare] = useState(null); @@ -54,7 +54,7 @@ const [activeSquare, setActiveSquare] = useState(null); // 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 =>