资讯专栏INFORMATION COLUMN

用React实现一个最最最简单的TodoList

Forest10 / 1852人阅读

摘要:初学,撸一个熟悉熟悉基本语法,只有最简单最简单的功能。引入这个之后,我们可以直接使用一些简单的组件,比如等,我们可以更加注重业务逻辑的实现。

初学React,撸一个TodoList熟悉熟悉基本语法,只有最简单最简单的功能。

如上图所示,是一个最简单的TodoList的样子了,我们应该怎样把它拆成一个个的组件呢?

在之前看来,可能就是这样一个HTML结构:

React的核心思想是:封装组件。

我们也可以按照这个思路来进行组件设计

组件设计

从小到大,从内到外 ~

我是这样进行设计的。

除去按钮,input这些之外,

  • 是HTML中最小的元素,我们可以先每一个
  • 当成是一个最小的组件,也就是图中橙色框的部分,它对应着每一条内容,我们先把它命名为TodoItem吧。

  • 的父级元素是
      ,那就把它看作一个组件呗,图中位于上方的蓝色部分,命名为TodoList

      恩,此时Todo内容的展示组件已经是够的了,我们再来加一个添加Todo内容的组件AddTodoItem吧,命名貌似有点丑- -,图中位于下方的蓝色部分。

      最后就是最外层的红色部分了,它就是整个app的主体部分,包含着其它小组件,命名为TodoBox

      ok,暂时就这几个小组件 ~

      然我们开始愉快的撸代码吧 ~

      代码部分 Index

      先看看入口程序,很简单。

      var React = require("react");
      var ReactDOM = require("react-dom");
      import TodoBox from "./components/todobox";
      import "./../css/index.css";
      
      export default class Index extends React.Component {
        constructor(){
          super();
        };
        render() {
          return (
              
          );
        }
      }
      
      ReactDOM.render(,document.getElementById("example"))
      TodoItem

      让我们想想啊,对于每一条内容来说,需要什么呢?

      一个确认是否完成的checkbox [ ]

      一条内容text

      一个删除button

      zzzzzz.....其他的暂时先不加了~

      那不是太简单了 ~

    • 找工作啊找工作啊
    • 不不不,我们现在是在写React,要这样:

      import React from "react";
      import {Row, Col, Checkbox, Button} from "antd";
      
      export default class TodoItem extends React.Component {
        constructor(props) {
          super(props)
          this.toggleComplete = this.toggleComplete.bind(this)
          this.deleteTask = this.deleteTask.bind(this)
        }
        toggleComplete() {
          this.props.toggleComplete(this.props.taskId)
        }
        deleteTask() {
          this.props.deleteTask(this.props.taskId)
        }
        render() {
          let task = this.props.task
          let itemChecked
          if (this.props.complete === "true") {
            task = {task}
            itemChecked = true
          } else {
            itemChecked = false
          }
          return (
            
    • {task}
    • ) } }

      import {Row, Col, Checkbox, Button} from "antd"是引入Ant Design。

      我们采用 React 封装了一套 Ant Design 的组件库,也欢迎社区其他框架的实现版本。

      引入这个之后,我们可以直接使用一些简单的UI组件,比如Row,Col,Checkbox,Button等,我们可以更加注重业务逻辑的实现。

      TodoList

      接下来就是拿一个

        把item包起来呗:

        import React from "react";
        import TodoItem from "./todoitem";
        export default class TodoList extends React.Component{
          constructor(props) {
            super(props);
          }
          render(){
            var taskList=this.props.data.map(listItem=>
              
            )
            return(
              
          {taskList}
        ) } }
        AddTodoItem

        添加内容这个组件也比较简单,就只需要一个input和一个button即可:

        import React from "react";
        import ReactDOM from "react-dom";
        import {Row, Col, Form, Input, Button,notification } from "antd";
        export default class AddTodoItem extends React.Component {
          constructor(props) {
            super(props)
            this.saveNewItem = this.saveNewItem.bind(this)
          }
          saveNewItem(e) {
            e.preventDefault()
            let element = ReactDOM.findDOMNode(this.refs.newItem)
            let task = element.value
            if (!task) {
              notification.open({
                description: "Todo内容不得为空!",
            });
            } else {
              this.props.saveNewItem(task)
              element.value = ""
            }
          }
          render() {
            return (
              
        ) } }
        TodoBox

        我们的小组件已经都实现了,拿一个大box包起来呗 ~

        import React from "react";
        import TodoList from "./todolist";
        import AddTodoItem from "./addtodoitem";
        import {Button, Icon, Row, Col} from "antd";
        export default class TodoBox extends React.Component {
          constructor(props) {
            super(props)
            this.state = {
              data: [
                {
                  "id": "1",
                  "task": "做一个TodoList Demo",
                  "complete": "false"
                }, {
                  "id": "2",
                  "task": "学习ES6",
                  "complete": "false"
                }, {
                  "id": "3",
                  "task": "Hello React",
                  "complete": "true"
                }, {
                  "id": "4",
                  "task": "找工作",
                  "complete": "false"
                }
              ]
            }
            this.handleToggleComplete = this.handleToggleComplete.bind(this);
            this.handleTaskDelete = this.handleTaskDelete.bind(this);
            this.handleAddTodoItem = this.handleAddTodoItem.bind(this);
          }
          generateGUID() {
            return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
              var r = Math.random() * 16 | 0,
                v = c == "x" ? r : (r & 0x3 | 0x8)
              return v.toString(16)
            })
          }
          handleToggleComplete(taskId) {
            let data = this.state.data;
            for (let item of data) {
              if (item.id === taskId) {
                item.complete = item.complete === "true" ? "false" : "true"
              }
            }
            this.setState({data})
          }
          handleTaskDelete(taskId) {
            let data = this.state.data
            data = data.filter(task => task.id !== taskId)
            this.setState({data})
          }
          handleAddTodoItem(task) {
            let newItem = {
              id: this.generateGUID(),
              task,
              complete: "false"
            }
            let data = this.state.data
            data = data.concat([newItem])
            this.setState({data})
          }
          render() {
            return (
              

        React TodoList

        ) } }

        注意:

        通过props传递子组件需要的值和方法

        传递方法时一定要bind(this),不然内部this会指向不正确

        源码

        完整的Demo代码在这:https://github.com/axuebin/react-todolist

        原文地址:http://axuebin.com/blog/2017/...

        文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

        转载请注明本文地址:https://www.ucloud.cn/yun/84384.html

        相关文章

        • 如何优雅设计 React 组件

          摘要:尽管现在的已不再那么流行,但的设计思想还是非常值得致敬和学习的,特别是的插件化。那么,如何解决我们回顾下的生命周期,父组件传递到子组件的的更新数据可以在中获取。当然,如何设计取决于你自己的项目,正所谓没有最好的, 作者:晓冬本文原创,转载请注明作者及出处 如今的 Web 前端已被 React、Vue 和 Angular 三分天下,一统江山十几年的 jQuery 显然已经很难满足现在的开...

          Anchorer 评论0 收藏0
        • React + Ramda: 函数式编程尝鲜

          摘要:每当的值改变后,我们只需要重新调用方法即可现在,让我们来实现一个类似风格的归约函数,以不断的递增。归约函数是不允许修改当前状态的,所有最简单的实现方式就是。 原文:Functional Components with React stateless functions and Ramda 阅读本文需要的知识储备: 函数式编程基本概念(组合、柯里化、透镜) React 基本知识(组件、...

          tomener 评论0 收藏0
        • 通过 React + Mobx 实现简单 TodoList

          摘要:子组件中通过就可以拿到上的数据了,实现了从父组件子组件的数据传递。当前状态改变时要发生的副作用。通过装饰器调用的函数进行使用。理想情况下,大部分组件都应该是无状态组件,仅通过获得数据。通过调用中的改变状态。 Todo-list 这是一个用来初步了解如何通过 React + Mobx 构建应用的 DEMO,通过 Webpack 进行打包。技术栈: React + Mobx + React...

          philadelphia 评论0 收藏0
        • 实例讲解react+react-router+redux

          摘要:而函数式编程就不一样了,这是模仿我们人类的思维方式发明出来的。数据流在中,数据的流动是单向的,即从父节点传递到子节点。数据流严格的单向数据流是架构的设计核心。 前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应用的过程。 代码地址:Re...

          RiverLi 评论0 收藏0

        发表评论

        0条评论

        Forest10

        |高级讲师

        TA的文章

        阅读更多
        最新活动
        阅读需要支付1元查看
        <