How to do it...

We are going to make a Todo list with some animations:

  1. First, let's create our Todo component:
import React, { Component } from 'react';
import uuidv4 from 'uuid/v4';
import List from './List';
import './Todo.css';

class Todo extends Component {
constructor() {
super();

// Initial state...
this.state = {
task: '',
items: []
};
}

componentWillMount() {
// Setting default tasks...
this.setState({
items: [
{
id: uuidv4(),
task: 'Default Task 1',
completed: false
},
{
id: uuidv4(),
task: 'Default Task 2',
completed: true
},
{
id: uuidv4(),
task: 'Default Task 3',
completed: false
}
]
});
}

handleOnChange = e => {
const { target: { value } } = e;

// Updating our task state with the input value...
this.setState({
task: value
});
}

handleOnSubmit = e => {
// Prevent default to avoid the actual form submit...
e.preventDefault();

// Once is submited we reset the task value and we push the
// new task to the items array.

this.setState({
task: '',
items: [
...this.state.items,
{
id: uuidv4(),
task: this.state.task,
complete: false
}
]
});
}

markAsCompleted = id => {
// Finding the task by id...
const foundTask = this.state.items.find(
task => task.id === id
);

// Updating the completed status...
foundTask.completed = true;

// Updating the state with the new updated task...
this.setState({
items: [
...this.state.items,
...foundTask
]
});
}

removeTask = id => {
// Filtering the tasks by removing the specific task id...
const filteredTasks = this.state.items.filter(
task => task.id !== id
);

// Updating items state...
this.setState({
items: filteredTasks
});
}

render() {
return (
<div className="Todo">
<h1>New Task:</h1>

<form onSubmit={this.handleOnSubmit}>
<input
value={this.state.task}
onChange={this.handleOnChange}
/>
</form>

<List
items={this.state.items}
markAsCompleted={this.markAsCompleted}
removeTask={this.removeTask}
/>
</div>
);
}
}

export default Todo;
File: src/components/Todo/index.jsx

  1. Now, in our List component, we need to include ReactCSSTransitionGroup and use it as a wrapper in our list elements. We need to specify the name of our transition using the transitionName prop, and transitionAppear adds a transition at the first animation mount. By default, it is false:
import React from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import './List.css';

const List = props => (
<ul>
<ReactCSSTransitionGroup
transitionName="todo"
transitionAppear={true}
>
{props.items.map((item, key) => (
<li
key={key}
className={`${item.completed ? 'completed' : 'pending'}`}
>
{item.task}

<div className="actions">
<span
className={item.completed ? 'hide' : 'done'}
onClick={() => props.markAsCompleted(item.id)}
>
<i className="fa fa-check"></i>
</span>

<span
className="trash"
onClick={() => props.removeTask(item.id)}
>
<i className="fa fa-trash"></i>
</span>
</div>
</li>
))}
</ReactCSSTransitionGroup>
</ul>
);

export default List;
File: src/components/Todo/List.jsx

  1. Now, using transitionName, we will add some styles using the special classes that are created by ReactCSSTransitionGroup:
.todo-enter {
opacity: 0.01;
}

.todo-enter.todo-enter-active {
opacity: 1;
transition: opacity 0.5s ease;
}

.todo-leave {
opacity: 1;
}

.todo-leave.todo-leave-active {
opacity: 0.01;
transition: opacity .5s ease-in;
}

.todo-appear {
opacity: 0.01;
transition: opacity .5s ease-in;
}

.todo-appear.todo-appear-active {
opacity: 1;
}
File: src/components/Todo/List.css
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset