4
\$\begingroup\$

Task Description:

  • Create a div-element and take control over it using a Vue-Instance.

  • Print an array of hobbies into the div-element. Provide some default hobbies.

  • Add a 'New Hobby' button and a text-input element. So that the user
    can add additional hobbies.

  • When a hobby list-item is clicked, it shall be removed from the list.

  • Add a "Hobby deleted"-paragraph which is only shown when a hobby-item has been deleted at least one time.

  • Above the list of hobbies add a hobby-counter which shows the current count of hobby-items.

  • Style the hobby-list depending on whether you have more or less then 3 hobbies in the list.

  • Outsource your hobbies (the list-item elements) into a component (so that it becomes re-usable).

The source-code of my solution:

// ----- index.js ----------
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
// --------- App.js ----------
import React, { Component } from 'react';
import { Hobbies } from './Hobbies';
import './App.css';
class App extends Component {
 render() {
 return (
 <div className="App">
 <Hobbies />
 </div>
 );
 }
}
export default App;
// ------------ Hobbies.js --------------
import React, { Component } from 'react';
import { HobbyItem } from './HobbyItem';
class Hobbies extends React.Component {
 constructor(props) {
 super(props);
 this.state = {
 hobbies: [
 'Reading',
 'Sport',
 'Music',
 'Chess',
 'Cooking'
 ],
 deleted: false
 }
 }
 addHobby(event) {
 let currentHobbies = this.state.hobbies;
 let textBox = event.target.previousElementSibling;
 if (textBox.value) {
 currentHobbies.push(textBox.value);
 textBox.value = '';
 this.setState({
 hobbies: currentHobbies
 });
 }
 }
 removeHobby(event) {
 let currentHobby = event.target.textContent;
 let updatedHobbies = this.state.hobbies.filter((hobby) => {
 return currentHobby !== hobby;
 });
 this.setState({
 hobbies: updatedHobbies
 });
 !this.state.deleted && this.setState({
 deleted: true
 });
 }
 render() {
 let cssHobbyItem = 'hobby-item';
 let cssCounter = 'more-three';
 let hobbyItems = this.state.hobbies.map((hobby, i) => {
 return <li onClick={this.removeHobby.bind(this)}
 className={cssHobbyItem}
 key={cssHobbyItem + i}>{hobby}</li>;
 });
 let hobbiesLength = this.state.hobbies.length;
 if (hobbiesLength < 3) {
 cssCounter = 'less-three';
 } else if (hobbiesLength === 3) {
 cssCounter = 'equal-three';
 }
 return (
 <div className="hobbies-list">
 <nav className="nav-add">
 <input type="text" id="input-add" />
 <button id="new-hobby"
 onClick={this.addHobby.bind(this)}>New Hobby</button>
 </nav>
 <p>{this.state.deleted && 'Hobby Deleted!'}</p>
 <p className={cssCounter} ><b>Count of Hobbies:
 </b> {this.state.hobbies.length}</p>
 <ul>
 {hobbyItems}
 </ul>
 </div>
 );
 }
}
export { Hobbies };
// --------- HobbyItem.js ---------------
import React, { Component } from 'react';
class HobbyItem extends React.Component {
 render() {
 return (
 <li></li>
 );
 }
}
export { HobbyItem }

Working Live-Demo

Is it all done in a good way and manner?

What would you do differently and why?

Looking forward to reading your comments and answers.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jan 1, 2018 at 8:51
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Disclaimer: I know sqat about react.js. I only have some minor nitpicks.


When the body of an anonymous function is a single line, instead of ... => { return value; }, you can write more compactly as ... => value, for example here:

let updatedHobbies = this.state.hobbies.filter((hobby) => currentHobby !== hobby);

Although this works, I think it's an unusual writing style, and it would be better to spell it out as an if statement:

!this.state.deleted && this.setState({
 deleted: true
});

When I saw this code, it made me curious what happens for other values of hobbiesLength, that is, what would be in an else block:

if (hobbiesLength < 3) {
 cssCounter = 'less-three';
} else if (hobbiesLength === 3) {
 cssCounter = 'equal-three';
}

The answer to that is a couple of lines higher up:

let cssCounter = 'more-three';

If you move this to the else block, then all the possible values of cssCounter will become easily visible in one place, which will be easier to read and understand.

answered Jan 1, 2018 at 13:05
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.