One of your components will be a list of all the authors who have quotations. You define this first draft of the Authors
component in src/Authors.js
:
export function Authors(props) {
return (
<div id="authors-panel" className="panel">
<h3>Authors</h3>
<ul>
<li>author1</li>
<li>author2</li>
<li>author3</li>
<li>...</li>
</ul>
</div>
);
}
The Authors
component gets nested inside of your App
component:
function App() {
return (
<div className="App">
<Authors />
</div>
);
}
In a project that uses prop-drilling, App
would have the quotations database as its state and then pass down the list of authors to Authors
as a prop. You don't need to do that here since you have a store that is globally accessible. Instead, you call a function named useSelector
from within the Authors
component to pull out the state that you need. If you wanted the whole quotations object, you'd write:
import {useSelector} from 'react-redux';
export function Authors(props) {
const quotations = useSelector(state => state.quotations);
// ...
}
However, you don't want the whole quotations object. You just want the author names, which are the keys of the object:
export function Authors(props) {
const authors = useSelector(state => Object.keys(state.quotations));
// ...
}
You have just pulled the authors out of the global store without doing any prop drilling. Not only does useSelector
give you the state that you need, but it also registers a dependency for your component. Whenever the list of authors changes, the component will automatically re-render.
The authors array is mapped to an array of list items:
export function Authors(props) {
// ...
return (
<div id="authors-panel" className="panel">
<h3>Authors</h3>
<ul>
{authors.map(author => <li>{author}</li>)}
</ul>
</div>
);
}
When you view your project in the browser, do you see the authors from the initial state? Try adding another author. When you check the browser console, you should see a warning message. How can you fix it?
Recall that whenever you have a JavaScript expression embedded in JSX that returns an array of components, each must have a unique key prop. You decide to use the author's name as a key:
{authors.map(author => <li key={author}>{author}</li>)}
Probably this is a decision that will come back to haunt you. Names aren't always unique. You promise to someday give each author a unique identifier.