手记

【备战春招】第7天 React零基础入门到实战,完成企业级项目简书网站开发——React基础篇

课程名称

课程章节

第3章 React基础精讲

  • 3-6 TodoList 代码优化

课程讲师

课程内容

  • TodoList代码优化
    • 用es6的解构赋值语法,直接取props对应属性
    • 先引入组件,再引入样式
    • bind函数写在render中会影响很多性能,一般建议把this指向的绑定写在构造函数中。
    • React标签的属性较多,可以用回车将其隔开。
    • 代码过长的话,进行函数拆分
    • 新版setState接收一个函数,而不是一个对象了,该函数需要有一个返回值,返回这个需要改变的对象。
    • prevState参数的使用
    • 注意:key值一定要放在循环的最外层元素上,否则是没有用的。

课程收获

TodoList代码优化

    render(){
        return(
            <div onClick={this.handleClick}>{this.props.content}</div>
        )
    }

    handleClick(){
        this.props.deleteItem(this.props.index);
    }

可以用es6的解构赋值语法,直接取props对应属性

    render(){
        const {content} = this.props;
        return(
            <div onClick={this.handleClick}>
                {content}
            </div>
        )
    }

    handleClick(){
        const {deleteItem,index} = this.props;
        deleteItem(index);
    }

一般情况下时先引入组件,再引入样式

import React, { Component, Fragment } from "react";
import TodoItem from "./TodoItem"
import "./style.css"

● bind函数写在render中会影响很多性能,一般建议把this指向的绑定写在构造函数中。
● 比如input的属性较多,可以用回车将其隔开。
● jsx其实展示的就是页面的内容,这里写了js的map语法,实际这里又融合了一些逻辑,这样致使jsx看起来非常长,一般可以再写一个方法,getTodoItem,将这块放入,然后替换成方法即可。这样jsx里面内容就很精简了。
● 注意:当在代码中,写得一坨一坨的时候,就可以做函数和代码上的拆分了。

TodoList

 <Fragment>
                <div>
                    {/* 下面是一个input框 */}
                    {
                        // 下面是一个input框
                    }
                    <label htmlFor="InputArea">输入内容</label>
                    <input
                        id="InputArea" 
                        className="input"
                        value={this.state.inputValue}
                        onChange={this.handleInputChange.bind(this)}
                    ></input>
                    <button onClick={this.handleBtnClick.bind(this)}>提交</button>
                </div>
                <ul>
                    {
                        this.state.list.map((item,index) => {
                            // return <li 
                            // key={index} 
                            // onClick={this.handleDelItem.bind(this, index)}
                            // dangerouslySetInnerHTML={{__html:item}}
                            // ></li>
                            return <TodoItem 
                            content = {item}  
                            index = {index} 
                            deleteItem = {this.handleDelItem.bind(this)}
                            />
                        })
                    }
                </ul>
            </Fragment>

=>

import React, { Component, Fragment } from "react";
import TodoItem from "./TodoItem"
import "./style.css"

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

        this.state = {
            inputValue: "",
            list: ["完成数学作业","完成语文作业"]
        }

        this.handleInputChange = this.handleInputChange.bind(this)
        this.handleBtnClick = this.handleBtnClick.bind(this)
        this.handleDelItem = this.handleDelItem.bind(this)

    }

    render(){
        return (
            <Fragment>
                <div>
                    {/* 下面是一个input框 */}
                    {
                        // 下面是一个input框
                    }
                    <label htmlFor="InputArea">输入内容</label>
                    <input
                        id="InputArea" 
                        className="input"
                        value={this.state.inputValue}
                        onChange={this.handleInputChange}
                    ></input>
                    <button onClick={this.handleBtnClick}>提交</button>
                </div>
                <ul>
                    {this.getTodoItem()}
                </ul>
            </Fragment>
        )
    }

    handleInputChange(e){
        this.setState({
            inputValue: e.target.value
        })
    }

    handleBtnClick(){
        this.setState({
            list:[...this.state.list, this.state.inputValue],
            inputValue:""
        })
    }

    handleDelItem(index){
        const dest = [...this.state.list];
        dest.splice(index, 1);

        this.setState({
            list: dest
        })
    }

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

export default TodoList;

我们这里setState都是使用对象的方式进行数据变更,但是新版本中已经不推荐此写法了。
新版setState接收一个函数,而不是一个对象了,该函数需要有一个返回值,返回这个需要改变的对象。

    handleInputChange(e){
        this.setState(() => {
            return {
                inputValue: e.target.value
            }
        })

        // this.setState({
        //     inputValue: e.target.value
        // })
    }

还可es6简写 => 不要return了,直接一个小括号即可。

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

老版本输入input可能会报错,那是因为setState传递一个函数,setState实际是异步的,应当先将获取的e.target.value保存为一个临时变量,然后再在异步函数中使用。

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

实际setState传递一个函数,它里有一个参数为prevState,代表修改数据之前的那一次的数据,它其实就等价于this.state。

    handleBtnClick(){
        this.setState(()=>({
            list:[...this.state.list, this.state.inputValue],
            inputValue:""
        }))
        // this.setState({
        //     list:[...this.state.list, this.state.inputValue],
        //     inputValue:""
        // })
    }

等价于:

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

其实这种写法更靠谱,避免修改state的状态。

    handleDelItem(index){
        this.setState((prevState) => {
            const list = [...prevState.list];
            list.splice(index, 1);

            return {list}
        })

        // const dest = [...this.state.list];
        // dest.splice(index, 1);

        // this.setState({
        //     list: dest
        // })
    }

解决key值的问题:key值暂时定为index,实际当前index在数组中是唯一的。

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

注意:key值一定要放在循环的最外层元素上,否则是没有用的。

0人推荐
随时随地看视频
慕课网APP