龙空技术网

通过实例学习React生命周期函数:componentWillMount

前端达人 54

前言:

目前兄弟们对“component生命周期”大概比较注意,咱们都需要学习一些“component生命周期”的相关文章。那么小编同时在网络上收集了一些对于“component生命周期””的相关内容,希望朋友们能喜欢,你们一起来了解一下吧!


大家好,在前面的几篇文章中,我们已经初步学习了组件的使用方法,但是这些内容只是开始,关于组件的内容还是比较多,比如在组件生命周期内提供了处理数据的方法,在特定的应用场景更新我们的应用,这对我们开发十分重要,因此我们有必要深入学习。在接下来的几篇文章里,我经通过实例的方式和大家一起学习组件生命周期相关的主要方法,本篇文章我们将通过一个待办事项的例子(Todo list)来深入学习如何使用 componentWillMount 函数。

componentWillMount 函数介绍

componentWillMount 函数的触发时机是在组件将要装载,在组件render之前调用。与其相对的是另外一个函数 componentDidMount,在组件加载完成, render之后调用,关于这个函数的介绍,将会在下一篇文章进行介绍。

有一点需要说明的是,componentWillMount 函数将会在未来 v17.0 版本中被移除,在目前最新的 v16.12 版本中还能够使用,但是你会在浏览器控制台里收到如下的信息警告:

如何修复以上的错误问题,我们可以使用 UNSAFE_componentWillMount 方法来替代 componentWillMount。虽然在未来的版本中即将废弃,但是不妨碍我们现在使用,还是有必要了解下的。

Todo list 实例

1、首先我们来看看本示例完成后的效果,如下图所示,首先界面初始化一些历史任务信息,我们可以进行更新完成状态同时可以进行删除,输入框用于添加新任务

2、接下来基于上篇文章的项目代码,我们在 components 目录创建一个 Todo 的文件夹,然后新建 Todo.js、Todo.css 文件 ,以下为 Todo 组件的基本结构代码:

import React, { Component } from 'react';import './Todo.css';class Todo extends Component {    constructor() {        super();    }    componentWillMount() {    }    render() {        return (            <div className="Todo">                <h1>New Task:</h1>            </div>        );    }}export default Todo;// File: src/components/Todo/Todo.js”

3、然后我们在构造函数中初始化本地的数据状态,对于任务列表 Todo list,我们需要定义任务(task)及列表数组(items )

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

4、接下来我们开始定义 componentWillMount() 方法,这个方法我们在文章的开头提及过了,在组件被渲染之前调用,这个例子,我们在组件 render 之前初始化我们的任务数据,由于在目前的版本使用 componentWillMount() 有警告提示,在未来的17版本中将会被删除,在这里我们使用了 UNSAFE_componentWillMount() 进行了替代,示例代码如下:

UNSAFE_componentWillMount() {        this.setState({            items:[                {                    id: uuidv4(),                    task: 'Pay the rent',                    completed: false                },                {                    id: uuidv4(),                    task: 'Go to the gym',                    completed: false                },                {                    id:uuidv4(),                    task:'Do my homework',                    completed:false                }            ]        });    }

5、在上述初始化数据时,我们使用了 uuidv4() 方法,这里我们需要安装相关的第三方依赖包,安装命令如下:

npm install uuid

6、接下来我们在文件的开头引入第三方依赖:

import uuidv4 from 'uuid/v4';

7、定义完默认数据状态后,我们需要定义组件的外观,即 render() 渲染相关的内容——我们的任务列表(Todo list)示例代码如下:

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>    );}

8、上述的组件 JSX 分为两个部分,第一部分是输入表单,关联我们的数据状态 this.state.task 部分,当用户提交表单时,我们保存新添加的任务,到任务列表数组中。第二部分是调用任务列表组件,我们传递了 items 数组 和 操作任务完成状态方法(markAsCompleted)和 删除任务方法(removeTask)这三个属性。

9、接下来我们来看看 handleOnChange() 方法,这个方法和我们的数据状态task数据关联,示例代码如下:

handleOnChange = e => {    const { target: { value } } = e;    // Updating our task state with the input value...    this.setState({        task: value    });}

10、接着我们来继续定义我们的表单提交方法 handleOnSubmit(), 这个方法主要是将我们新添加的数据保存到任务数组中,示例代码如下:

  handleOnSubmit = e =>{      e.preventDefault();      if (this.state.task.trim() !==''){          this.setState({              task:'',              items:[                  ...this.state.items,                  {                      id: uuidv4(),                      task: this.state.task,                      complete:false                  }              ]          })      }    };

11、markAsCompleted() 方法接收一个任务 ID 标识参数,这个方法用于标识任务已完成,其逻辑主要先查找到对应 ID 的任务,将其更新已完成,然后刷新本地的数据状态,示例代码如下:

   markAsCompleted = id => {        const  foundTask = this.state.items.find(            task => task.id ===id        );        foundTask.completed = true;        console.log(this.state.items);        this.setState({            items:[                ...this.state.items            ]        });    };

12、接下来我们来定义任务删除方法 removeTask(),这个方法同 markAsCompleted() 一样,接收 ID 参数,用于移除对应任务,示例代码如下:

removeTask = id => {        const  filteredTasks = this.state.items.filter(            task => task.id !== id        );        this.setState({           items:filteredTasks        });    };

13、这样我们的 Todo 组件就完成了,让我们将代码组合在一起,完整的代码如下:

import React, {Component} from "react";import './Todo.css'import  uuidv4 from  'uuid/v4'import './List'import List from "./List";class Todo extends  Component{    constructor() {        super();        this.state={            task:'',            items:[]        };    }    handleOnChange = e => {        const { target: { value } } = e;        this.setState({            task: value        });    };    handleOnSubmit = e =>{      e.preventDefault();      if (this.state.task.trim() !==''){          this.setState({              task:'',              items:[                  ...this.state.items,                  {                      id: uuidv4(),                      task: this.state.task,                      complete:false                  }              ]          })      }    };   markAsCompleted = id => {        const  foundTask = this.state.items.find(            task => task.id ===id        );        foundTask.completed = true;        console.log(this.state.items);        this.setState({            items:[                ...this.state.items            ]        });    };    removeTask = id => {        const  filteredTasks = this.state.items.filter(            task => task.id !== id        );        this.setState({           items:filteredTasks        });    };    UNSAFE_componentWillMount() {        this.setState({            items:[                {                    id: uuidv4(),                    task: 'Pay the rent',                    completed: false                },                {                    id: uuidv4(),                    task: 'Go to the gym',                    completed: false                },                {                    id:uuidv4(),                    task:'Do my homework',                    completed:false                }            ]        });    }    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/Todo.js

14、然后我们来完成我们的列表展示组件,我们在 todo 目录下创建 List.js 文件,示例代码如下,代码比较简单,这里就不过介绍了。

import React from "react";const  List =  props => (    <ul>        {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>        ))}    </ul>);export  default  List;// File: src/components/Todo/List.js

15、在我们调用 map 函数渲染列表时,别忘记 key 这个属性加入到列表元素上,否则浏览器控制台将会收到如下的警告:

16、你可能注意到,在我们的界面中,我们引入了一些 Font Awesome 图标,我们需要在我们 index.html 文件引入图标的 CSS 文件,部分示例代码如下:

<head>    <title>React App</title>    <link        href=";        rel="stylesheet"    /></head>/* File: public/index.html */

17、最后我们来定义我们的组件样式,代码部分如下:

.Todo {    background-color: #f5f5f5;    border-radius: 4px;    border: 1px solid #e3e3e3;    box-shadow: inset 0 1px 1px rgba(0,0,0,.05);    margin-bottom: 20px;    margin: 50px auto;    min-height: 20px;    padding: 19px;    text-align: left;    width: 70%;}.Todo ul {    margin: 20px 0px;    padding: 0;    list-style: none;}.Todo ul li {    background-color: #fff;    border: 1px solid #ddd;    display: flex;    justify-content: space-between;    margin-bottom: -1px;    padding: 10px 15px;    position: relative;}.Todo ul li .hide {    border: 1px solid red;    visibility: hidden;}.Todo ul li.completed {    background-color: #dff0d8;}.Todo ul li .actions {    display: flex;    justify-content: space-between;    width: 40px;}.Todo ul li span {    cursor: pointer;}.Todo ul li .done {    color: #79c41d;    display: block;}.Todo ul li .trash {    color: #c41d1d;    display: block;}.Todo form input {    background-color: #fff;    border-radius: 4px;    border: 1px solid #ccc;    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);    color: #555;    font-size: 14px;    height: 34px;    line-height: 34px;    padding: 6px 12px;    width: 40%;}.Todo form button {    background: #2ba6cb;    border: 1px solid #1e728c;    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5) inset;    color: white;    cursor: pointer;    display: block;    font-size: 14px;    font-weight: bold;    line-height: 1;    margin: 20px auto;    padding: 10px 20px 11px;    position: relative;    text-align: center;    text-decoration: none;}/* File: src/components/Todo/Todo.css */

18、还有最后一步,我们别忘记修改我们的 App 组件,否则我们 Todo 核心组件将无法渲染,完成后代码如下:

import React from 'react';import './App.css';// 引入布局相关的组件import Header from "../shared/components/Header/Header";import Content from "../shared/components/Content/Content";import Footer from "../shared/components/Footer/Footer";import Todo from "./Todo/Todo";function App() {  return (    <div className="App">     <Header title="Todo List"/>        <Content>            <Todo/>        </Content>      <Footer/>    </div>  );}export default App;// File: src/components/App.js

19、如果你按照上述顺序正确完成后,接下来在控制台输入 npm run start 命令, 你将会看到如下界面:

数据首次加载初始化的界面:然后我们在输入框输入新的任务信息按下回车键后,你将会看到完成后的添加信息点击对应对号图标,标记对应的任务已完成点击垃圾箱图标,删除对应的任务小节

本节的内容就给大家介绍到这里,想必大家通过这个练习已经熟悉了 componentWillMount 函数的用法,在下一篇文章里我们继续通过做实例的形式,学习另外一个与其对应的方法 componentDidMount(),敬请期待...


《 React 手册》系列文章

「React 手册」在 React 项目中使用 ES6,你需要了解这些(一)

「React 手册」React 16 中值得你关注的新特性

「React 手册 」在 Windows 下使用 React , 你需要注意这些问题

「React 手册 」从创建第一个React组件开始学起

「React 手册 」关于组件属性(props)与状态(state)的介绍

「React 手册 」如何创建函数组件?

标签: #component生命周期