diff --git a/src/components/Programmers.js b/src/components/Programmers.js
index e34c4f392..c3c57fc2e 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...
@@ -27,6 +27,8 @@ 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 = () => {
// Leave this for last!
@@ -34,12 +36,21 @@ 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.
+
+ // for (let i = 0; i < programmers.length; i++) {
+ // if (programmers[i].id === featured) {
+ // return programmers[i].name;
+ // }
+ // }
+
+ const programmerObject = programmers.find(programmer => programmer.id === featured);
+ return programmerObject.name;
};
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 (
@@ -50,9 +61,9 @@ 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}
)
}
@@ -62,11 +73,11 @@ 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
+ featured
? `🎉 Let's celebrate ${getNameOfFeatured()}! 🥳`
: 'Pick an awesome programmer'
}
);
-}
+}
\ No newline at end of file
diff --git a/src/components/Spinner.js b/src/components/Spinner.js
index d0326fd34..155826389 100644
--- a/src/components/Spinner.js
+++ b/src/components/Spinner.js
@@ -37,24 +37,89 @@ 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 */
-
+ /* STEP 1 */
+ const [spinnerOn, setSpinnerOn] = useState(true);
const toggleSpinner = () => {
/* STEP 4 */
+ setSpinnerOn(!spinnerOn);
};
return (
Spinner
{
- true &&
--+--
/* STEP 2 */
+ spinnerOn &&
--+--
/* STEP 2 */
}
);
-}
+}
+
+/*
+// SPINNER Instructions
+
+// Watch this short video:
+// https://tk-assets.lambdaschool.com/38201164-4df9-4c89-923b-5325dc72124d_spinner.gif
+
+// How many slices of state do you think are necessary to act as "sources of truth" for all
+// the things that change in this widget? Give it some thought before continuing reading!
+
+// Our first impulse might be to say 2 different states:
+// - Whether the spinner is visible or not (perhaps this could be a boolean).
+// - Whether the text of the button reads "Show Spinner" or "Hide Spinner".
+
+// But a single slice of state is all that's needed here: whether spinner is on or not.
+// The text of the button can be derived from the value of that one slice of state.
+
+// STEP 0:
+// Start by studying the component below, and importing the state hook.
+
+// STEP 1:
+// Create a 'spinnerOn', 'setSpinnerOn' pair of variables using the state hook.
+// The 'spinnerOn' slice should be initialized to true so the spinner is visible on page load.
+
+// STEP 2:
+// This is called a logical expression. If the expressions on both sides of the '&&' are truthy,
+// the one on the right becomes the value of the whole line. If an expression on either side of the '&&'
+// is falsy, the one on the left becomes the value of the whole line. It's a neat little trick to render
+// a React element (in this case the spinner) conditionally: only if the variable on the left is truthy.
+
+// Replace the hard-coded 'true' with the variable that keeps track of whether spinner is on or not.
+
+// STEP 3:
+// Use a ternary expression inside the text of the button, to render "Hide" or "Show" depending on the value of 'spinnerOn'.
+
+// STEP 4:
+// This click handler needs to toggle the spinner by setting "whether on" to be the opposite of what it currently is.
+// Do you remember the operator we use to do "not"?
+// */
+
+// import React, {useState} from 'react'; /* STEP 0 */
+
+// export default function Spinner() {
+// /* STEP 1 */
+// const [spinnerOn, setSpinnerOn] = useState(true);
+// const toggleSpinner = () => {
+// /* STEP 4 */
+// setSpinnerOn(!spinnerOn);
+// };
+
+// return (
+//
+//
Spinner
+// {
+// spinnerOn &&
--+--
/* STEP 2 */
+// }
+// {/* STEP 3:
+// Use a ternary expression inside the text of the button, to render "Hide" or "Show" depending on the value of 'spinnerOn'. */}
+//
+//
+// );
+// }
diff --git a/src/components/Squares.js b/src/components/Squares.js
index 25ab72546..b1ad11822 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,13 +24,18 @@ 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, setSquares] = 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 ''
+
+ if (id === activeSquare) {
+ return 'active';
+ }
};
const markActive = id => {
@@ -38,6 +43,11 @@ export default function Squares() {
// 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).
+ if (id === activeSquare) {
+ setActiveSquare(null);
+ } else {
+ setActiveSquare(id);
+ }
};
return (
@@ -48,7 +58,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 =>
);
}
+
+
+// /*
+// SQUARES Instructions
+
+// Watch this short video:
+// https://tk-assets.lambdaschool.com/0aebd463-7c5e-4d0b-ad22-4da8f4b54e92_squares.gif
+
+// This component keeps track of a list of "square ids" on the one hand,
+// and the currently active id on the other. That's two slices of state!
+// One is used as the source of truth to render the squares, and the other
+// so that the component knows which square is currently active.
+
+// Only one square (or none) can be active at any given point.
+
+// Find comments below to help you along.
+// */
+
+// 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() {
+// // 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 [squares, setSquares] = 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 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).
+// if (id === activeSquare) {
+// setActiveSquare(null)
+// } else {
+// setActiveSquare(id);
+// }
+// };
+
+// return (
+//
+//
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!
+// squares.map(id =>
+//