React入门 - 09(TodoList & TodoItem 代码优化)

发布时间:2024年01月19日

本章内容

上一节内容续使用 ”TodoList“ 案例来讲解一下”组件拆分与组件传值“。观察里面的代码,发现有优化的地方很多。本节我们针对其中代码进行优化

TodoItem.js 代码优化

打开 TodoItem.js,我们需要优化的点有

  • 为了”性能“,我们统一把与 this绑定相关的代码都统一放到 constructor

  • 尽量是用 ES6的语法(例如 TodoItem.js中可以用到 ES6的”结构赋值“)

  • 下面来标记下需要优化的点

// 优化前代码
import React, { Component } from 'react'
class TodoItem extends Component {
  render () {
    return (
      // 优化点:把与 this 相关绑定的代码统一放到 constructor 中
      <div onClick={this.handleClick.bind(this)}>
        {/* 优化点:使用 ES6 的解构赋值 */}
        {this.props.content}
      </div>
    )
  }

  handleClick() {
    // 优化点:使用 ES6 的解构赋值
    this.props.deleteFn(this.props.index)
  }
}
export default TodoItem
  • 优化后打代码
import React, { Component } from 'react'

class TodoItem extends Component {
  constructor(props) {
    super(props)

    this.handleClick = this.handleClick.bind(this)
  }
  render () {
    const { content } = this.props
    return (
      // 优化点:把与 this 相关绑定的代码统一放到 constructor 中
      <div onClick={this.handleClick}>
        {/* 优化点:使用 ES6 的解构赋值 */}
        {content}
      </div>
    )
  }

  handleClick() {
    const { deleteFn, index } = this.props
    // 优化点:使用 ES6 的解构赋值
    deleteFn(index)
  }
}

export default TodoItem

TodoList.js 代码优化

打开 TodoList.js,我们需要优化的点有:

  • 同上,为了”性能“,我们统一把与 this绑定相关的代码都统一放到 constructor

  • JSX 中我们尽量只放页面显示的内容,逻辑代码尽量抽出来一个方法

  • 涉及”循环渲染列表“时,记得给每个循环的每一项添加 key值,现在暂时用 index(当然这是一种不好的方式,可能造成代码报错,具体好的方式等我们讲”虚拟DOM“时再补充)

  • 新版 React已经不推荐使用 this.setState({xxx: xxx})的方式来修改数据了,取而代之的是”传入函数“的形式进行.

  • 注意:

1、使用”函数“的形式去更改数据时,要注意的是,它会变成一个”异步“的 setState(后面讲 ”虚拟DOM“ 时再详细说一下为什么是需要”异步“),我们要”显示“的在外层对 value值进行保存,然后再在内层去使用它,否则报错

2、setState函数接受一个prevState参数,指的是修改数据前的 state是什么样的。所以在代码中,遇到”修改数据之前的 state“时(如:this.state.list),可以直接写成 prevState.list

3、使用 prevState的好处是可以避免不小心改动到了 state的状态

const value = e.target.value
this.setState(() => {
  inputValue: value
})
  • 下面来标记下需要优化的点
import React, { Component, Fragment } from "react";
import TodoItem from "./TodoItem";

class TodoList extends Component{
  constructor(props) {
    super(props)

    this.state = {
      inputValue: '', 
      list: []
    }
  }

  render() {
    return (
      <Fragment>
        <div>
          {/* this 的绑定同一放在 contructor 中 */}
          <input value={this.state.inputValue} onChange={this.changeInputValue.bind(this)} />
          {/* this 的绑定同一放在 contructor 中 */}
          <button onClick={this.addListData.bind(this)}> 提交 </button>
        </div>

        <ul>
          {/* JSX  中的逻辑代码尽量抽取成”方法“ */}
          {this.state.list.map((item, index) => {

            return (
              // this 的绑定同一放在 contructor 中
              <TodoItem content={item} index={index} deleteFn={this.deleteData.bind(this)}></TodoItem>
            
            )
          })}
        </ul>
      </Fragment>
    )
  }

  deleteData(index) {
    const list = [...this.state.list]
    list.splice(index, 1)
    // 改用新版 React 推荐的”函数“形式来变更数据
    this.setState({
      list: list
    })

  }

  addListData() {
    // 改用新版 React 推荐的”函数“形式来变更数据
    this.setState({
      list: [...this.state.list, this.state.inputValue]
    })
    // 改用新版 React 推荐的”函数“形式来变更数据
    this.setState({
      inputValue: ''
    })
  }

  changeInputValue(e) {
    // 改用新版 React 推荐的”函数“形式来变更数据
    this.setState({
      inputValue: e.target.value
    })
  }
}

export default TodoList
  • 优化后打代码
import React, { Component, Fragment } from "react";
import TodoItem from "./TodoItem";

class TodoList extends Component{
  constructor(props) {
    super(props)
    this.deleteData = this.deleteData.bind(this)
    this.addListData = this.addListData.bind(this)
    this.changeInputValue = this.changeInputValue.bind(this)
    this.state = {
      inputValue: '', 
      list: []
    }
  }

  render() {
    return (
      <Fragment>
        <div>
          <input value={this.state.inputValue} onChange={this.changeInputValue} />
          <button onClick={this.addListData}> 提交 </button>
        </div>

        <ul> {this.getTodoItem()} </ul>
      </Fragment>
    )
  }

  getTodoItem() {
    return this.state.list.map((item, index) => {
      return <TodoItem key={index} content={item} index={index} deleteFn={this.deleteData}></TodoItem>
    })
  }

  deleteData(index) {
    this.setState((prevState) => {
      const list = [...prevState.list]
      list.splice(index, 1)
      return {list}
    })

  }

  addListData() {
    this.setState((prevState) => ({
      list: [...prevState.list, prevState.inputValue],
      inputValue: ''
    }))
  }

  changeInputValue(e) {
    const value = e.target.value
    this.setState(() => ({inputValue: value})) 
  }
}

export default TodoList
  • 运行修改完的代码,看看页面效果(我这里运行后没有报错和警告)
    在这里插入图片描述

到此,本章内容结束!

文章来源:https://blog.csdn.net/qq_37600506/article/details/135698609
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。