Skip to main content
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Source Link
michael.zech
  • 4.5k
  • 8
  • 33
  • 56

React Exercise: Build a dynamic list application

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.