Skip to main content

--description--

The map array method is a powerful tool that you will use often when working with React. Another method related to map is filter, which filters the contents of an array based on a condition, then returns a new array. For example, if you have an array of users that all have a property online which can be set to true or false, you can filter only those users that are online by writing:

let onlineUsers = users.filter(user => user.online);

--instructions--

In the code editor, MyComponent's state is initialized with an array of users. Some users are online and some aren't. Filter the array so you see only the users who are online. To do this, first use filter to return a new array containing only the users whose online property is true. Then, in the renderOnline variable, map over the filtered array, and return a li element for each user that contains the text of their username. Be sure to include a unique key as well, like in the last challenges.

--hints--

MyComponent should exist and render to the page.

assert.strictEqual(
Enzyme.mount(React.createElement(MyComponent)).find('MyComponent').length,
1
);

MyComponent's state should be initialized to an array of six users.

assert(
Array.isArray(
Enzyme.mount(React.createElement(MyComponent)).state('users')
) === true &&
Enzyme.mount(React.createElement(MyComponent)).state('users').length === 6
);

MyComponent should return a div, an h1, and then an unordered list containing li elements for every user whose online status is set to true.

(() => {
const comp = Enzyme.mount(React.createElement(MyComponent));
const users = (bool) => ({
users: [
{ username: 'Jeff', online: bool },
{ username: 'Alan', online: bool },
{ username: 'Mary', online: bool },
{ username: 'Jim', online: bool },
{ username: 'Laura', online: bool }
]
});
const result = () => comp.find('li').length;
const _1 = result();
const _2 = () => {
comp.setState(users(true));
return result();
};
const _3 = () => {
comp.setState(users(false));
return result();
};
const _4 = () => {
comp.setState({ users: [] });
return result();
};
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
assert(
comp.find('div').length === 1 &&
comp.find('h1').length === 1 &&
comp.find('ul').length === 1 &&
_1 === 4 &&
_2_val === 5 &&
_3_val === 0 &&
_4_val === 0
);
})();

MyComponent should render li elements that contain the username of each online user.

(() => {
const comp = Enzyme.mount(React.createElement(MyComponent));
const users = (bool) => ({
users: [
{ username: 'Jeff', online: bool },
{ username: 'Alan', online: bool },
{ username: 'Mary', online: bool },
{ username: 'Jim', online: bool },
{ username: 'Laura', online: bool }
]
});
const ul = () => {
comp.setState(users(true));
return comp.find('ul').html();
};
const html = ul();
assert(
html ===
'<ul><li>Jeff</li><li>Alan</li><li>Mary</li><li>Jim</li><li>Laura</li></ul>'
);
})();

Each list item element should have a unique key attribute.

assert(
(() => {
const ul = Enzyme.mount(React.createElement(MyComponent)).find('ul');
console.log(ul.debug());
const keys = new Set([
ul.childAt(0).key(),
ul.childAt(1).key(),
ul.childAt(2).key(),
ul.childAt(3).key()
]);
return keys.size === 4;
})()
);

--seed--

--after-user-code--

ReactDOM.render(<MyComponent />, document.getElementById('root'));

--seed-contents--

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [
{
username: 'Jeff',
online: true
},
{
username: 'Alan',
online: false
},
{
username: 'Mary',
online: true
},
{
username: 'Jim',
online: false
},
{
username: 'Sara',
online: true
},
{
username: 'Laura',
online: true
}
]
};
}
render() {
const usersOnline = null; // Change this line
const renderOnline = null; // Change this line
return (
<div>
<h1>Current Online Users:</h1>
<ul>{renderOnline}</ul>
</div>
);
}
}

--solutions--

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [
{
username: 'Jeff',
online: true
},
{
username: 'Alan',
online: false
},
{
username: 'Mary',
online: true
},
{
username: 'Jim',
online: false
},
{
username: 'Sara',
online: true
},
{
username: 'Laura',
online: true
}
]
};
}
render() {
const usersOnline = this.state.users.filter(user => {
return user.online;
});
const renderOnline = usersOnline.map(user => {
return <li key={user.username}>{user.username}</li>;
});
return (
<div>
<h1>Current Online Users:</h1>
<ul>{renderOnline}</ul>
</div>
);
}
}