React学习笔记实战1:todo列表

对慕课网上的付费教程:React.js入门与实战中的todolist一章的源码分析.

Part 1 :达到目标

这里写图片描述

一个输入框,在其中输入内容后回车,其中的内容会显示在输入框下面:

这里写图片描述

点击对应的内容会消失.

Part 2:分析

首先,这里有两部分组成,第一,输入框,第二,展示区域,所以分别分为两个组件:Input.jsxList.jsx.按照教程上讲,这两个就是木偶组件,即只负责数据的传递与展示.在这之上还有另一个整合这两个组件的智能组件,负责数据的处理Todo.jsx

Todo.jsx

这里首先思考一个问题,我们操作的数据,即用户输入完成后保存在List.jsx中的数据保存在哪里?保存在List.jsx中吗?不能,因为这部分数据与Input.jsx中有关,当Input.jsx中需要传入新的值时,需要重新进行输出.那保存在Input.jsx中可以吗?可以,那么List.jsx还有什么存在的意义吗?所以,当涉及到两个组件的公共数据时,都是保存在调用这两个组件的父组件上的.即Todo.jsx中的.

import React from 'react'
impoer Input from 'Input'
import List from 'List'

class Todo extends React.Component{
    constructor(props,context){
        super(props,context);
        this.state={
            // 保存Input.jsx和List.jsx的公共值
            todos:[]
        }
    }
    render(){
        return(
            <div>
                <Input submitFn={this.submitFn.bind(this)}/>
                <List todos={this.state.todos} deleteFn={this.deleteFn.binf(this)}
            </div>
        )
    }
}

暂时就看这么多,可以看到在Todo.jsx中调用Input.jsxList.jsx组件时,还向其中传递了两个函数对象参数submitFndeleteFn,并将数据this.state.todos作为参数传递到下层组件去.这里思考一下,传递的这几个参数作用是什么?

答案揭晓:

  • submitFn:将用户最新的输入传递到this.state.todos中进行输出
  • deleteFn:给List.jsx调用,来操作Todo.jsx中的this.state.todos
  • todos:将数据传递给List.jsx进行输出.

submitFn

submitFn(value){
    // 获取 this.state.todos数组的下一个下标,当作id
    const id=this.state.todos.length;
    // 调用this.setState来修改this.state的值
    this.setState({
        // concat 的作用是连接两个数组,即旧的this.state.todos和{id:id,text:value}
        todos:this.state.todos.concat({
            id:id,
            text:value
        })
    })
}

注意,这里的submitFn等于是Todo.jsx中开放给Input.jsx操作父级组件中的this.state.todos的一个函数,一个函数,所以可以需要设置传入的参数value

deleteFn

类似的,deleteFn就是Todo.jsx开放给List.jsx来删除父组件中的this.state.todos的值的.

deleteFn(id){
    let data=this.state.todos;
    this.setState({
        // ES6语法 ()=>{}
        // 这里表名,如果当前项的id与传入的id不相同,则返回真,否则返回false
        todos:data.filter(item=>{
            if(item.id!==id){
                return item
            }
        })
    });
}

Input.jsx

首先,输入值肯定是保存在state中的,并且需要为该输入框绑定onChange事件,并且我们需要实现,在输入完成后可以按Enter键将内容传递到List.jsx中进行输出.所以基本结构就是这样:

import React from 'react'

class Input extends React.Component{
    constructor(props,context){
        super(props,context);
        // 初始化 state,设置value来保存输入框输入
        this.state={
            value:""
        }
    }
    render(){
        return(
            <div>
                <input 
                    {/*绑定value的值*/}
                    value={this.state.value}
                    {/*绑定表单内容change事件*/}
                    onChange={this.changeHandler.bind(this)}
                    {/*绑定键盘单击事件*/}
                    onKeyUp={this.keyUpHandler.bind(this)}
            </div>
        )
    }
}

事件的命名规则一般是XXXHander

接下来重点就是绑定的这两个事件该怎么写了,changeHandler是简单的,就是将最新的输入值保存进this.state.value中:

changeHandler(event){
    this.setState({
        value:event.target.value
    });
}

这里的event参数的传入是依据ES5的标准,所以不需要在上面进行显式的指定.

接下来就是键盘单击事件了,这里需要实现的目标是当用户点击Enter键,并且输入框内数据不为空时,将数据传递到List.jsx中进行输出.具体实现就是需要父级Input.jsx中传入的函数对象参数:submitFn了,具体调用方式如下:

keyUpHandler(event){
    const value=this.state.value;
    // 当用户单击Enter键并且输入值不为空
    if(event.keyCode===13 && value.trim()){
        // 注意这里的调用方式:this.props
        this.props.submitFn(value);
        // 之后可以清空一下输入框,提升用户体验
        this.setState({value:""})
    }
}

这样就实现了,当用户输入完成后,正确的输入值会被保存在Input.jsx中的this.state.todos中了.

List.jsx

这一组件的作用其实就两个,第一,输出内容,第二,绑定单击事件,用于实现单击时删除功能.

import React from 'react'

class List extends React.Component{
    render(){
        // 获取从父级传入进来的参数
        var data=this.props.todos;
        // 根据传入参数进行输出
        return (
            <div>
                <ul>
                    {/*由于这里的输出跟父级的this.state.todos绑定了,所以在父级中修改this.state.todos就能自动实现自动重新输出了*/}
                    {data.map((item,index)=>{
                        return <li key={index} onClick={this.clickHandler.bind(this,item.id)}>{item.text}</li>
                    })}
                </ul>
            </div>
        )
    }
    // 创建删除函数,删除的功能通过调用父级的函数实现
    clickHandler(id){
        this.props.deleteFn(id);
    }
}

export default List

Part 3 总结

所谓智能组件和木偶组件,其中Todo.jsx在其中的作用就是智能组件,负责数据处理,输出控制,而List.jsxInput.jsx则是木偶组件,仅负责采集数据,输出数据,调用智能组件提供的接口,将数据传回智能组件进行处理.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值