Links to codepen exercises.
https://codepen.io/bzzz-coding/pen/dyKVvMR
https://codepen.io/bzzz-coding/pen/poKWebM
const users = [
{ name: "John Doe", id: 1 },
{ name: "Jane Doe", id: 2 },
{ name: "Billy Doe", id: 3 }
]
{/* inside function App() return: */}
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
https://codepen.io/bzzz-coding/pen/JjZrWyN
In the beginning, I was trying to toggle .hidden in the className of the div, and added disply: none; to .hidden in css. Then, I realized that I can just use a ternary operator on the entire div element. This way, there is no need for className or css.
Tip: ternary operators can be used for className, text content, or an entire element.
function App() {
const [showMsg, setShowMsg] = React.useState(true);
const toggle = () => {
setShowMsg(!showMsg);
};
return (
<>
<button onClick={toggle}>
{showMsg ? "Hide Element Below" : "Show Element Below"}
</button>
{showMsg && <div>Toggle Challenge</div>}
</>
);
}
https://codepen.io/bzzz-coding/pen/JjZrWqM
- Have each attribute on separate line;
- Set value to {text};
- Don't forget to pass in e in onChange for input
function App() {
const [text, setText] = React.useState("");
return (
<>
<input
onChange={(e) => setText(e.target.value)}
value={text}
type="text"
placeholder="Enter Text"
/>
<p>{text}</p>
</>
);
}
https://codepen.io/bzzz-coding/pen/gOKGGaJ
At first, I was trying to "hide" the entire button with
{text.length > 0 && <button>Submit</button>}
However, this is not "disable" means. Instead, I should use the disabled attribute. The disabled attribute also prevents the onClick event from firing.
function App() {
const [value, setValue] = React.useState("");
return (
<>
<h3>Disable Button Challenge</h3>
<input type="text" onChange={(e) => setValue(e.target.value)} />
<button disabled={value.length < 1}>Submit</button>
</>
);
}
The code below (although not part of this exercise), shows how to disable a button once it has been clicked.
function App() {
const [value, setValue] = React.useState("");
const [clicked, setClicked] = React.useState(false)
return (
<>
<h3>Disable Button After It Has Been Clicked Once</h3>
<button onClick={() => setClicked(true)} disabled={clicked}>{clicked ? 'You have clicked this button' : 'You can click this button once'}</button>
</>
);
}
https://codepen.io/bzzz-coding/pen/xxzXXeM
My solution was to create a function called updateText, and passed it down using prop updateParentText to the child:
function Child({updateParentText}) {
return (
<>
<div>Child</div>
<button onClick={updateParentText}>Change Parent Value</button>
</>
);
}
function Parent() {
const [value, setValue] = React.useState(
"I need to be updated from my child"
);
const updateText = () => {
setValue('Text updated!')
}
return (
<>
<h3>Update Parent State Challenge (Using Callback)</h3>
<div className="wrapper">
<div>Parent</div>
<div className="box-wrapper">{value}</div>
</div>
<div className="wrapper">
<Child updateParentText={updateText} />
</div>
</>
);
}
ReactDOM.render(<Parent />, document.getElementById("root"));
The solution code passed down setValue instead of updateParentText. I'm not sure which is better, but the code looks simpler this way:
function Child({ setValue }) {
return (
<>
<div>Child</div>
<button onClick={() => setValue("Parent has been updated!")}>
Change Parent Value
</button>
</>
);
}
function Parent() {
const [value, setValue] = React.useState(
"I need to be updated from my child"
);
return (
<>
<h3>Update Parent State Challenge (Using Callback)</h3>
<div className="wrapper">
<div>Parent</div>
<div className="box-wrapper">{value}</div>
</div>
<div className="wrapper">
<Child setValue={setValue} />
</div>
</>
);
}
https://codepen.io/bzzz-coding/pen/dyKVmzY
- props.children Whenever the Parent component is invoked {children} will be displayed. This is a reference to what is between the opening and closing tags of the Parent component.
function Child() {
return <div>This is children content</div>;
}
// Add code only here
function Parent({children}) {
return (
<div>
<h3>Parent Component</h3>
{children}
</div>
);
}
function App() {
return (
<Parent>
<Child />
</Parent>
);
}
My Solution: https://codepen.io/bzzz-coding/pen/QWxOWVr Solution: https://codepen.io/angelo_jin/pen/BawrWzy
- Even when setting input type to "number", the
e.target.value
onChange has a type of String. My solution was to convert the two number strings into numbers in the addNums function. However, I could also do the conversion in the input onChange:
onChange={(e) => setNumber1(+e.target.value)}
- Total was set to 0 in useState, so the paragraph would show "Total: 0" if I add {total} to the
tag:
<p>Total: {total}</p>
. The solution used<p>Total: {total || ""}</p>
to avoid displaying 0 before calculation.
https://codepen.io/bzzz-coding/pen/OJEOJax
https://codepen.io/bzzz-coding/pen/WNyXNqK
- Taking advantage of the impure function inside useEffect to fetch data from URL, reset userData, and leave an empty dependency array that acts like componentDidMount as in--only runs once.
const [userData, setUserData] = React.useState({});
const getUserData = async () => {
const response = await fetch(url);
const jsonData = await response.json();
setUserData(jsonData);
};
React.useEffect(() => {
getUserData();
}, []);
https://codepen.io/bzzz-coding/pen/WNyXvBR