如何使用react實現todolist

2022-12-29 14:00:37

使用react實現todolist的方法:1、新建一個專案資料夾Code;2、通過「create-react-app todo-list」命令建立react專案;3、在components資料夾下新建ToDoList.jsx檔案;4、使用一個陣列來儲存資料,陣列中每個元素為一個物件;5、編寫頁面佈局;6、新增鍵盤事件,監聽輸入變化,實現待辦事項和已辦事項即可。

本教學操作環境:Windows10系統、react18.0.0版、Dell G3電腦。

如何使用react實現todolist?

React入門實戰範例——ToDoList實現

摘要:

最近學習了一小段時間的React,對一些React開發元件的基礎有了一點認識,跟著教學視訊,自己實現了一個ToDoList元件的功能,今天把做這個元件的過程記錄一下,加深學習印象,給同樣的前端入門者做一個參考。

一、範例展示和功能介紹

1.1 範例展示

e5c04c3c4bd92c9371090e7023b36e4.jpg

視訊1.1

1.2 功能介紹

  • 新增待辦事項,按enter鍵確定,同時清空輸入框;
  • 通過checkbox是否勾選可以切換待辦和已辦事項;
  • 點選刪除可以刪除事項

二、準備工作

2.1 環境設定提醒

準備之前:本文假定開發環境已設定完成,包括:

  • Node.js已安裝;
  • cnpm 已安裝; npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 腳手架工具已安裝; npm install -g create-react-app / cnpm install -g create-react-app

注意:初次設定腳手架會出現禁止執行指令碼的錯誤,解決辦法點選:

2.2 新建React專案

1.新建一個專案資料夾Code,使用VSCode,將Code檔案加新增到工作區;

圖2.1

2.右擊Code資料夾,在索引標籤中選擇在終端中開啟;

圖2.2

3.在終端中輸入如下命令,新建React專案: create-react-app todo-list

圖2.3

4.生成Rreact專案如下 :

圖2.4

React開發主要是對src裡的檔案動手腳,node_modules主要防止各種依賴包,public放置一些公共檔案,package.json這些是一些組態檔,在此不詳述。

2.3 檔案分類

  • 在src目錄下新建components資料夾,用來放置自己建立的元件;
  • 在src目錄下新建assets檔案加用來防止css檔案和圖片檔案等靜態資源;

如圖2.5所示:

圖2.5

三、實現過程

3.1 建立元件ToDoList

components資料夾下新建ToDoList.jsx檔案,編寫如下程式碼,搭好一個元件的基本框架;程式碼如下:

//匯入React相關依賴
import React from 'react';

//建立一個元件
class ToDoList extends React.Component{
    //建構函式
    constructor(props){
        super(props);
        //this是父元件(類)的一個範例,範例就類似於java裡的一個類,建立了這個型別的一個物件,這個物件就是範例
        this.state = {
            //this.state裡可以寫一些初始化的資料
        }
    }


    //render渲染虛擬DOM
    render(){

        return(
            <div>
                ToDoList
            </div>
        );
    }

}


//輸出元件,使得該元件可以被其他元件呼叫
export default ToDoList;
登入後複製
元件中每個部分的功能,在註釋裡有簡略描述。一個基本的元件一般包括以上的幾個部分:
  • import匯入的依賴;
  • 元件(class XXX extends React,Component);
  • 建構函式constructor;
  • render函數;
  • export輸出元件;

3.2 功能實現與解析

1.初始化資料

使用一個陣列來儲存資料,陣列中每個元素為一個物件,該物件包括兩個欄位:title和checked,tile為字串型別,checked為布林型別,用來區分待辦(false)已辦(true);

 list:[
                {
                    title:'吃飯',
                    checked:true
                },
                {
                    title:'跑步',
                    checked:false
                },
                {
                    title:'上班',
                    checked:false
                },
                {
                    title:'睡覺',
                    checked:true
                },
       ]
登入後複製

該陣列在this.state中初始化:

 constructor(props){
        super(props);
        //this是父元件(類)的一個範例,範例就類似於java裡的一個類,建立了這個型別的一個物件,這個物件就是範例
        this.state = {
            //this.state裡可以寫一些初始化的資料
            list:[
                {
                    title:'吃飯',
                    checked:true
                },
                {
                    title:'跑步',
                    checked:false
                },
                {
                    title:'上班',
                    checked:false
                },
                {
                    title:'睡覺',
                    checked:true
                },
            ],
        }
    }
登入後複製

2.編寫頁面佈局

頁面分為頂部的輸入框(input)和下面的 待辦事項列表 已辦事項列表;在render中的return中編寫(jsx);

    render(){

        return(
            <div>
                 <header>TodoList:  <input type = "text"/> </header>

                <h2>待辦事項</h2>

                <hr />
                
                <ul>
                    {/* 多個li,後面會迴圈輸出 */}
                    <li>
                        <input type="checkbox" /> -- <button>刪除</button>
                    </li>
                </ul>           



                <h2>已完成事項</h2>

                <hr />
                <ul>
                    {/* 多個li,後面會迴圈輸出 */}
                    <li>
                        <input type="checkbox"  /> -- <button>刪除</button>
                    </li>
                </ul>    
            </div>
        );
    }
登入後複製

3.掛載到根節點下

在index.js下,引入ToDoList元件

import ToDoList from './components/ToDoList';
登入後複製

然後掛在元件ToDoList

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import ToDoList from './components/ToDoList';

ReactDOM.render(
  <React.StrictMode>
    {/* 此處是ToDoList元件 */}
    <ToDoList />   
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
登入後複製

簡陋渲染效果如下:

圖3.1

3.功能實現

  • 新增待辦事項

(1)使用ref屬性,獲取input輸入值:

  在input標籤上設定屬性ref="inputToDo",然後在方法中可以通過 this.refs.inputToDo.value獲取輸入值;

(2)新增鍵盤事件,監聽輸入變化,當輸入enter時,新增待辦事項;

  使用onKeyUp(鍵盤彈起)/onKeyDown(鍵盤按下)事件來監聽鍵盤變化。當鍵盤變化後,觸發新增函數,將輸入值新增到待辦事項中;程式碼如下:

jsx:

<header>TodoList:  <input type = "text" ref = "inputToDo" onKeyUp = {this.addToDo}/> </header>
登入後複製

addToDo函數:

    addToDo = (event) => {
        console.log(event.keyCode);
        if(event.keyCode === 13)
        {
            let tempList = this.state.list;
            tempList.push({
                title:this.refs.inputToDo.value,
                checked:false,
            });
            this.setState({
                list:tempList,
            });
            this.refs.inputToDo.value = '';
        }
    }
登入後複製

(3)在constructor中使用bind繫結addToDo,這一步是必須的,否則方法不能執行,所有的方法都需要像這樣繫結;

 this.addToDo = this.addToDo.bind(this);
登入後複製

圖3.2

效果:

 2422c8247807bfdd88fad9d264f846f.jpg

視訊3.1

  • 輸出待辦事項和已辦事項

  使用map方法,迴圈遍歷陣列,輸出每組資料;程式碼如下:

 <ul>
                    {/* 多個li,後面會迴圈輸出 */}
                    {
                        this.state.list.map((value,index)=>{
                {/*checked為false表示待辦*/}
                            if(!value.checked)
                            {
                                return (
                                    <li>
                         {/* */}
                                        <input key = {index} type="checkbox" checked = {value.checked} onChange={this.checkboxChange.bind(this,index)}/> {value.title}-- <button>刪除</button>
                                    </li>
                                );
                            }

                        })
                    }
 </ul>
登入後複製

checked = {value.checked}表示核取方塊是否打勾,onChange事件觸發一個改變事項狀態的方法,index是陣列的索引,該方法在下文實現;

  效果:

圖3.3

  • 待辦和已辦互相轉換

  這一步的思路也很簡單,其實就是在觸發checkboxonChange事件時,將某一個事項的checked值變為相反的值(true->false/false->true),所以onChange後的方法需要傳入陣列的索引值,具體實現程式碼如下:

jsx

<input key = {index} type="checkbox" checked = {value.checked} onChange={this.checkboxChange.bind(this,index)}/> {value.title}-- <button>刪除</button>
登入後複製

checkboxChange

checkboxChange = (index) => {
      let tempList = this.state.list;
      tempList[index].checked = !tempList[index].checked;
      this.setState({
          list:tempList,
     });
}
登入後複製

效果:

126027da24d1d7684ce5a4297cd51d5.jpg

 視訊3.2

  • 刪除事項

刪除事項比較簡單了,思路也是類似的,在button上新增onClick按鈕,觸發刪除事件,傳入引數index,然後根據index,使用陣列的splice函數,刪除某一待辦事項。

arrayA.splice(index,n)
登入後複製

該方法第一個引數是陣列中的元素位置,第二個引數是從index開始刪除多少個元素。

具體實現如下:

jsx

  <li>
       <input key = {index} type="checkbox" checked = {value.checked} onChange={this.checkboxChange.bind(this,index)}/> {value.title}
       -- <button onClick={this.removeToDo.bind(this,index)}>刪除</button>

 </li>
登入後複製

removeToDo

    removeToDo = (index) => {
        let tempList = this.state.list;
        tempList.splice(index,1);
        this.setState({
            list:tempList,
        });
    }
登入後複製

效果:即為開篇展示的效果

3.3 編寫樣式

樣式隨便寫了一下,不太好看,這裡也把程式碼丟上來吧;

index.css

.list{

  padding: 10px;
}

.list li{

  line-height: 40px;
  margin-left: 30px;
}

.title{

  height: 44px;

  line-height: 44px;

  text-align: center;

  background: #000;

  color:#fff;
}

.title input{

  height: 40px;
}


.container{
  width: 800px;
  height: 1000px;
  margin-left: auto;
  margin-right: auto;
  background-color:  #D0D0D0;
  border: #fff solid 1px;
  border-radius: 5px;
}

.container h2{
  margin-left: 20px;
}

.del-btn {
  float: right;
  margin-right: 30px;
}
登入後複製
  • 引入樣式

  在ToDoList.jsx中按如下程式碼引入index.css

import '../assets/index.css';
登入後複製

3.4 整體效果

d273095292e556a84429dacc9169a03.jpg

視訊3.3:整體效果展示

四、整體程式碼

  • ToDoList.jsx
//匯入React相關依賴
import React from 'react';
import '../assets/index.css';

//建立一個元件
class ToDoList extends React.Component{
    //建構函式
    constructor(props){
        super(props);
        //this是父元件(類)的一個範例,範例就類似於java裡的一個類,建立了這個型別的一個物件,這個物件就是範例
        this.state = {
            //this.state裡可以寫一些初始化的資料
            list:[
                {
                    title:'吃飯',
                    checked:true
                },
                {
                    title:'跑步',
                    checked:false
                },
                {
                    title:'上班',
                    checked:false
                },
                {
                    title:'睡覺',
                    checked:true
                },
            ],
        }

        this.addToDo = this.addToDo.bind(this);
        this.checkboxChange = this.checkboxChange.bind(this);
    }

    addToDo = (event) => {
        console.log(event.keyCode);
        if(event.keyCode === 13)
        {
            let tempList = this.state.list;
            tempList.push({
                title:this.refs.inputToDo.value,
                checked:false,
            });
            this.setState({
                list:tempList,
            });
            this.refs.inputToDo.value = '';
        }
    }


    checkboxChange = (index) => {
        let tempList = this.state.list;
        tempList[index].checked = !tempList[index].checked;
        this.setState({
            list:tempList,
        });
    }

    removeToDo = (index) => {
        let tempList = this.state.list;
        tempList.splice(index,1);
        this.setState({
            list:tempList,
        });
    }

    //render渲染虛擬DOM
    render(){

        return(
            <div>
                 <header className = "title">TodoList:  <input type = "text" ref = "inputToDo" onKeyUp = {this.addToDo}/> </header>
                    <div className = "container">
                        <h2>待辦事項</h2>

                        <hr />

                        <ul className = "list">
                            {/* 多個li,後面會迴圈輸出 */}
                            {
                                this.state.list.map((value,index)=>{
                                    if(!value.checked)
                                    {
                                        return (
                                            <li>
                                                <input key = {index} type="checkbox" checked = {value.checked} onChange={this.checkboxChange.bind(this,index)}/> {value.title}
                                                <button onClick={this.removeToDo.bind(this,index)} className = "del-btn">刪除</button>
                                            </li>
                                        );
                                    }

                                })
                            }
                        
                        </ul>           
                        <h2>已完成事項</h2>

                        <hr />
                        <ul className = "list">
                            {/* 多個li,後面會迴圈輸出 */}
                            {
                                this.state.list.map((value,index)=>{
                                    if(value.checked)
                                    {
                                        return (
                                            <li>
                                                <input key = {index} type="checkbox" checked = {value.checked} onChange={this.checkboxChange.bind(this,index)}/> {value.title}
                                                <button onClick={this.removeToDo.bind(this,index)} className = "del-btn">刪除</button>
                                            </li>
                                        );
                                    }
                                })
                            }
                        </ul>    
                 </div>               
            </div>
        );
    }

}


//輸出元件,使得該元件可以被其他元件呼叫
export default ToDoList;
登入後複製
View Code
  • index.css 

.red{

  color:red;
}


.list{

  padding: 10px;
}

.list li{

  line-height: 40px;
  margin-left: 30px;
}

.title{

  height: 44px;

  line-height: 44px;

  text-align: center;

  background: #000;

  color:#fff;
}

.title input{

  height: 40px;
}


.container{
  width: 800px;
  height: 1000px;
  margin-left: auto;
  margin-right: auto;
  background-color:  #D0D0D0;
  border: #fff solid 1px;
  border-radius: 5px;
}

.container h2{
  margin-left: 20px;
}

.del-btn {
  float: right;
  margin-right: 30px;
}
登入後複製
  • index.js 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import ToDoList from './components/ToDoList';

ReactDOM.render(
  <React.StrictMode>
    {/* <App /> */}
    <ToDoList />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
登入後複製

五、結語

結語就算了吧,好睏,睡了。

寫部落格費時間啊,大家要是看到有啥不對的地方,麻煩聯絡我修改哈,我水平太有限了,謝謝大佬們了。

推薦學習:《》

以上就是如何使用react實現todolist的詳細內容,更多請關注TW511.COM其它相關文章!