Implement the basic ToDolist with react
The last time I learned how to build a basic react framework, today I'll try to write a ToDolist to exercise my logic ability
First, we should build a basic framework and fill in two sets of default data
import React, { Component } from 'react'; class App extends Component { constructor(props) { super(props); this.state = { list: [ { title: 'react', done: true }, { title: 'react2', done: false } ] } } render() { return ( <div> <p>ToDolist</p> </div> ); } } export default App;
In this way, the words to dolist will be displayed on our page, and then the data will be rendered and referenced.
import React, { Component } from 'react'; class App extends Component { constructor(props) { super(props); this.state = { list: [ { title: 'react', done: true }, { title: 'react2', done: false } ] } } render() { return ( <div> <p>ToDolist</p> {this.state.list.map(item => <div className='item' key={item.title}> <input type="checkbox" /> <span>{item.title}</span> <button>x</button> </div>)} </div> ); } } export default App;
In this way, two list tags with basic information will be displayed on our page, as shown in the figure:
Next, let's implement the delete function, add a click event to the button, and pass the parameters:
<div> <p>ToDolist</p> {this.state.list.map(item => <div className='item' key={item.title}> <input type="checkbox" /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} </div>
Write the delItem method above render()
delItem = item => { var list = this.state.list; //Caching list is convenient for subsequent code calls var ind = list.findIndex(value => value.title === item.title);//Find the index of the list with the same value as the parameter title list.splice(ind, 1);//Delete corresponding element this.setState({ list })//Update list }
Well, back to our page, you can delete the elements.
Next, let's implement the function of filtering events, and divide the completed events and to be completed events into two categories. First, we need to filter the list. Here we need to use the filter filtering method
<div> <p>ToDolist</p> <h3>underway{this.state.list.filter(item => !item.done).length}</h3> //Filter out the number in the list where done is false (when the filter filters out true, it will return, and if it reverses to true, it indicates that it was originally false, which is a bit around here, which can be abstractly understood as double negative and positive) {this.state.list.map(item => <div className='item' key={item.title}> <input type="checkbox" /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} </div>
In this way, we can get the number of unfinished tasks. Similarly, we can filter out the number of completed tasks:
<div> <p>ToDolist</p> <h3>underway{this.state.list.filter(item => !item.done).length}</h3> //Filter out the number in the list where done is false (when the filter filters out true, it will return, and if it reverses to true, it indicates that it was originally false, which is a bit around here, which can be abstractly understood as double negative and positive) {this.state.list.map(item => <div className='item' key={item.title}> <input type="checkbox" /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} <h3>Already completed{this.state.list.filter(item => item.done).length}</h3> </div>
The results are as follows:
The quantity has been filtered out, but the task classification has not reached the correct position. Therefore, we only need to filter the list data before rendering. The code is as follows:
<div> <p>ToDolist</p> <h3>underway{this.state.list.filter(item => !item.done).length}</h3> //Filter out the number in the list where done is false (when the filter filters out true, it will return, and if it reverses to true, it indicates that it was originally false, which is a bit around here, which can be abstractly understood as double negative and positive) {this.state.list..filter(item => !item.done).map(item => <div className='item' key={item.title}> <input type="checkbox" /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} <h3>Already completed{this.state.list.filter(item => item.done).length}</h3> {this.state.list..filter(item => item.done).map(item => <div className='item' key={item.title}> <input type="checkbox" /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} </div>
OK, so each list has its own correct position:
Now click the small box in front to change the task state, and bind the input state to the task state. First, add a click event to the previous input:
<div> <p>ToDolist</p> <h3>underway{this.state.list.filter(item => !item.done).length}</h3> {this.state.list.filter(item => !item.done).map(item => <div className='item' key={item.title}> <input type="checkbox" checked={item.done} onChange={this.checkItem.bind(this, item)} /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} <h3>Already completed{this.state.list.filter(item => item.done).length}</h3> {this.state.list.filter(item => item.done).map(item => <div className='item' key={item.title}> <input type="checkbox" checked={item.done} onChange={this.checkItem.bind(this, item)} /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} </div>
Attribute binding has been implemented. Next, write the function. The overall and deletion methods are almost the same. After finding the corresponding element, carry out the corresponding operation. The code is as follows:
checkItem = item => { var list = this.state.list; //Caching list is convenient for subsequent code calls var ind = list.findIndex(value => value.title === item.title);//Find the index of the list with the same value as the parameter title list[ind].done = !list[ind].done;//Reverse the input confirmation of the corresponding subscript list this.setState({ list })//Update list }
Go back to the page and click to classify
Next, to implement the add function, you need to reference the createRef method of react to obtain nodes
import React, { Component, createRef } from 'react'; class App extends Component { constructor(props) { super(props); this.state = { list: [ { title: 'react', done: true }, { title: 'react2', done: false } ] } this.tempRef = createRef();
Then we add an input content to the page for node binding, add events for button binding, and finally update the list data.
import React, { Component, createRef } from 'react'; class App extends Component { constructor(props) { super(props); this.state = { list: [ { title: 'react', done: true }, { title: 'react2', done: false } ] } this.tempRef = createRef(); } delItem = item => { var list = this.state.list; //Caching list is convenient for subsequent code calls var ind = list.findIndex(value => value.title === item.title);//Find the index of the list with the same value as the parameter title list.splice(ind, 1);//Delete corresponding element this.setState({ list })//Update list } checkItem = item => { var list = this.state.list; //Caching list is convenient for subsequent code calls var ind = list.findIndex(value => value.title === item.title);//Find the index of the list with the same value as the parameter title list[ind].done = !list[ind].done;//Reverse the input confirmation of the corresponding subscript list this.setState({ list })//Update list } addItem = () => { var list = this.state.list;//Caching list is convenient for subsequent code calls var inp = this.tempRef.current;//Cache input list.unshift({ title: inp.value, done: false });//Add a new element to the list. The default value is incomplete false this.setState({ list })//Update list inp.value = '' } render() { return ( <div> <p>ToDolist</p> <input type="text" ref={this.tempRef} /> <button onClick={this.addItem}>add to</button> <h3>underway{this.state.list.filter(item => !item.done).length}</h3> {this.state.list.filter(item => !item.done).map(item => <div className='item' key={item.title}> <input type="checkbox" checked={item.done} onChange={this.checkItem.bind(this, item)} /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} <h3>Already completed{this.state.list.filter(item => item.done).length}</h3> {this.state.list.filter(item => item.done).map(item => <div className='item' key={item.title}> <input type="checkbox" checked={item.done} onChange={this.checkItem.bind(this, item)} /> <span>{item.title}</span> <button onClick={this.delItem.bind(this, item)}>x</button> </div>)} </div> ); } } export default App;