Lesson 8 - children
July 20, 2016 · View on GitHub
Now we've got menu items which receive props telling them if they're active, and will internally change their state if they're hovered or clicked.
How do we change which menu item is currently active?
The currently active menu sounds like it should be part of a state for some
Menu component: it's something that can change over time, but not something
that should be passed down to MenuItem components.
We already have the beginnings of a Menu component in our src/js/index.js,
the <ul> element.
Challenge 10
Extract the <ul> element out into a new file menu.js which exports a Menu
component.
Notes:
- Don't forget to
requireMenuItem.
Now that we have multiple menu items, it might make sense to be able to pass in the menu's text as a prop.
Challenge 11
Pass a prop name to each MenuItem to be rendered as the text of that menu.
Notes:
- When rendering you need to escape the prop by wrapping it in curly braces
- Make sure you set a default prop value
MenuItem is a very generic component - all of its display is now controlled by
either passing in props, or reacting to events (hovering / clicks).
This allows us to make the display of these components data driven. Ie; let's move the required info into an array:
src/js/menu.js
let items = [
'Home',
'Search',
'About',
'Contact'
]
// ...
Then we can loop over this array and convert each item into a new MenuItem:
src/js/menu.js
// ...
render: function() {
let menuItems = items.map(function(item, index) {
return <MenuItem key={index} name={item} />
})
// ...
}
If you're not familiar with the functional paradigm map, see the docs for
Javascript's implementation
here
You can see we're passing in an extra prop key to each MenuItem instance.
This correlates to the index of the array, but could be any unique identifier
for this collection. React uses the key prop internally to identify this
component as unique from the others.
menuItems is now an array of MenuItem components. We can render this the
same way we render any other javascript value, by wrapping it in curly braces
({menuItems}). React is smart enough to detect it as an array and render each
item it contains individually.
Challenge 12
Use the array format from above to render the menu items.
Note:
- Don't foget to add the
keyprop, or you'll get errors in the DevTools console.
Uh-oh, looks like we've lost the ability to set isActive on one of the menus.
As posed at the top of this lesson: How do we change which menu item is currently
active?
The Menu component is built on the same state system as MenuItem, so we can
take advantage of that to store which is currently active.
When rendering each item, we can pass in the isActive prop like so:
// ...
render: function() {
let activeMenu = this.state.activeMenu
let menuItems = items.map(function(item, index) {
if (activeMenu === index) {
return <MenuItem key={index} name={item} isActive={true} />
} else {
return <MenuItem key={index} name={item} />
}
})
// ...
}
Challenge 13
Set an initial state for activeMenu to 1 (ie; the second menu item in the
array), and correctly set the prop isActive on the corresponding menu item as
per above
Lesson 7 - state « | Home | » Lesson 9 - reusability