来个大佬优化下react代码...

新人上路!学习react

之前工作中使用的vue, 现在想学习react

先跟着官网的例子写完了一个#字棋,列举的几个任务也写完了,
然后找了一个b站某个学习视频给出的效果图改的
image.png

期望:
优化简写下代码...
感觉很多地方重复了,并且不优雅...
比如,每个方法里面我都去const items = [...this.state.items]

另外一个就是 搜索的时候返回的结果: itemsitem这种写法有没有更好的表达呢?

大佬,拜托了。

以下代码是一个集合了增删查的TodoList

import React, { Component } from 'react'
class Input extends Component {
  render () {
    return (
      <li >
        <div>
          <input type="text" placeholder='添加任务' onInput={this.props.onAdd}/> 
          <button onClick={this.props.onClick}>添加任务</button>
        </div>
        <div>
        <input className="header" placeholder='搜索任务' onInput={this.props.onInput} type="text"/>
        </div>
      </li>
    )
  }
}
class CheckAll extends Component {
  render () {
    return (
      <li>
        {this.props.value} {this.props.item.length}
        <input type="checkbox"  checked={this.props.value === this.props.item.length && this.props.value !== 0}  onChange={this.props.onChange}/>
         已完成{this.props.value}/ 全部{this.props.item.length}
         <button onClick={this.props.onClick}>清除已完成任务</button>
      </li>
    )
  }
}
class Todo extends Component {
  constructor(props) {
    super(props)
    this.state = {
      items: [
        {
          title: '吃饭',
          checked: false,
        },
        {
          title: '吃饭2',
          checked: false,
        },
        {
          title: '吃饭3',
          checked: false,
        },
        {
          title: '吃饭4',
          checked: false,
        },
        {
          title: '睡觉',
          checked: false,
        },
        {
          title: '不睡觉',
          checked: false,
        },
        {
          title: '想睡觉',
          checked: false,
        },
        {
          title: '打代码',
          checked: false,
        },
      ],
      value: 0, //  选中数量
    }
    this.state.item = this.state.items
  }
  //  复选框事件
  handleChange(i) {
    const item = this.state.item
    let num = 0
    item.map((e,v) => {
     if (e.title === i.title) {
        e.checked = !e.checked
     }
     return  this.setState({
       // 选中数字加 1
       value: e.checked? num = num +1: num
     })
    })
    this.setState({
      item: item,
    })
  }
  //  删除指定元素
  handleClickDelete (i) {
    let item = this.state.item
    let index = item.indexOf(i)
    item.splice(index, 1)
    //  用原始数据取过滤当前点击删除的元素,返回不包含当前点击元素的数组
    let res = this.state.items.filter(e=> e !== i)
    this.setState({
      item: item,
      items: res,
      //  判断是否选中状态下删除
      value: i.checked?this.state.value - 1: this.state.value
    });
  }
  //  全选/全不选
  handleCheckAll () {
    const item = [...this.state.item]
    item.filter((e) => {
      return e.checked = this.state.value === this.state.item.length?false: true
    })
    this.setState ({
      value:this.state.value === this.state.item.length?0:this.state.item.length,
      item:item
    })
  }

   //  删除所有选中
   handleClickDeleteChecked () {
    let item = [...this.state.item]
    item = item.filter((e,v)=> !e.checked)
    let res = this.state.items.filter(e => !e.checked)
    this.setState({
      item: item,
      items:res,
      value: 0,
    })
  }

  //  搜索
  handleSearch (e) {
    const value = e.target.value
    const items = [...this.state.items]
    let res = items.filter((e,v) => e.title.includes(value)) //  匹配结果
    this.setState({
      item: res,
    })
    
  }

  //  添加任务
  handleClickAdd () {
    const val = this.state.INPUT_VALUE
    if(val) {
      let item = {
        title: val,
        checked: false,
      }
      const items = [...this.state.items]
      items.push(item)
      this.setState({
        items:items,
        item:items,
      })
    } else {
      alert('请输入有效数据')
    }
  }

  //  输入内容
  handleOnAdd (e) {
    this.setState({
      INPUT_VALUE: e.target.value
    })
  }
 
  renderList (e) {
   return  e.map(i => {
      return (
        <li key={i.title}>
          <input type="checkbox" checked={i.checked} onChange={()=> this.handleChange(i)} />
          <span>{i.title}</span>
          <button onClick={()=> this.handleClickDelete(i)}>删除</button>
        </li>
      )
    })
  }

  render() {
    return (
      <div>
          <ul>
            <Input  onInput={(e) => {this.handleSearch(e)}} onAdd={(e)=>{this.handleOnAdd(e)}} onClick={()=> {this.handleClickAdd()}}/>
            {this.renderList(this.state.item)}
            <CheckAll 
              value={this.state.value} 
              item={this.state.item}
              onClick={()=> {this.handleClickDeleteChecked()}}
              onChange={()=> { this.handleCheckAll()}}
              />
          </ul>
      </div>
    )
  }
}

export default Todo

阅读 1.7k
3 个回答

emmm,优化是无止境的,只能对代码提出点建议。。
1.简单的组件可以使用函数组件来替代,CheckAll也可以根据这个改

const Input = ({onAdd, onClick, onInput}) => <li>
    <div>
        <input type="text" placeholder='添加任务' onInput={onAdd}/>
        <button onClick={onClick}>添加任务</button>
    </div>
    <div>
        <input className="header" placeholder='搜索任务' onInput={onInput} type="text"/>
    </div>
</li>

另外你维护的items基本没用到,就很奇怪。。如果你认为items只是个原始数据源的话,他应该不存储checked的,存到selectItemKey就好了。搜索的话直接通过一个searchValue去filter items。
handleChange事件也很奇怪。value更新的太频繁了。直接在更新item后计算总数即可。(handleClickDelete也可以用同样方式计算。甚至可以抽象一个方法。

使用title作为删除key明显不合理。增加任务的时候没有同名检测。

    //  搜索
    handleSearch(e) {
        const searchValue = e.target.value
        this.setState({
            searchValue
        })
    }
    // render里面对应的list,从需求场景看 items的长度应该在一个可控的范围,内存筛选不会有较大的性能问题。 可以以此值代替以前的item
    {this.renderList(this.state.items.filter(({title}) => title.includes(searchValue)))}

最后就是搜索部分 目前为完成搜索设计的太复杂啦。改造成这样就可以获得到搜索的列表了

    //  复选框事件
    handleChange(title) {
        const {selectDict} = this.state;
        this.setState({selectDict: {...selectDict, [selectDict[title]]: !selectDict[title]}})
    }
    // renderList
    <input type="checkbox" checked={selectDict[i.title]} onChange={() => this.handleChange(title)}/>

通过Object.values(selectDict).filter(Boolean).length就能得到当前搜索的总数。
至于勾选是否要保留搜索前结果。这个就根据需求自行设计吧。大概就这些了。

对学习提个"优化",最好是学最新的react hook~

去了解下Redux和Saga,再去学习Dva,系统的学完了这些,那你自然知道代码要如何会更优雅。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题