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

来源:互联网 发布:泰安房产每日成交数据 编辑:程序博客网 时间:2024/06/07 16:57

对慕课网上的付费教程: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则是木偶组件,仅负责采集数据,输出数据,调用智能组件提供的接口,将数据传回智能组件进行处理.

原创粉丝点击