react简单实现todolist

最近因为工作需要,开始学习react,在读了基础部分的文档之后,决定写一个todolist来练习。功能十分简单,简单的增加删除。涉及到一些可以总结的部分,还是有部分涉及不到的地方,以后再谈。

开始

这里我直接用了官方的cli工具create-react-app,安装过程如下

npm install -g create-react-app
create-react-app my-app

cd my-app
npm start

index.js为入口文件,首先要引入相关的js文件

import ReactDOM from "react-dom";
import React from "react";
import "./index.css";

jsx

说到react,就不得不提到jsx,何为jsx,其实完全可以就理解为js,只不过里面有不加引号的html代码段,举个例子:

        <li key={index}>
          {li}
          <span onClick={this.delList} data-id={index}>
            x
          </span>
        </li>

这里是我return出来的语句,可以看到原来是html的部分都是那样,在html中的{}表示的就是js的语句了。

组件

可以理解为每一个react.Component对象就是一个组件,由于js里不存在纯粹意义上的class,即使是es6也只是用语法糖做了一些处理,所以定义组件有两种写法。
一、使用function
二、使用class
这里更推荐使用class,由于react基本就是和babel一起使用,所以学会新的方法很有必要,建议去mdn上搜索class看看文档。
具体用法:

class XXX extends React.Component

注意要大写,在渲染的时候在页面中标签也要是大写,比如这里的<Todos/>,原因是小写会识别为标准的html标签


ReactDOM.render(<Todos />,document.getElementById("root"));

更多细节参考文档,重点说明父子组件通信的问题,这里我设计了两个组件。

结构示意图

父组件Todos包括确定按钮和ul元素,子组件list则是所有列表的集合。
react有个原则是:
组件不能直接操作其它组件,而数据是从父到子单项传递的
这里,要说明两个参数props,state。state表示自身可以捕捉到改变的值,props则来自于父组件。
这里我在父组件Todo里,设置了state

  state = {
    list: [1, 2, 3],
    targetValue:'work'
  };

这里面的list就是要传递到子组件的值,我们在子组件上定义

         <List
            additem={this.state.item}
            tolist={this.state.list}
            onChange={this.listChange}
          />

而在子组件,就可以用

this.props.tolist

获取到list的值了,那么在父组件增加list的值,刷新state,子组件就会更新。
删除的方法绑定在子组件上,要如何去影响父组件的list呢?
这里要使用回调了,首先在子组件的每一项上绑定相应的方法

          <span onClick={this.delList} data-id={index}>
            x
          </span>

然后通过props通知给父组件

  delList(e) {
    let index = e.target.getAttribute("data-id");
    this.props.onChange(index);
  }

父组件标签部分绑定相应的方法

          <List
            additem={this.state.item}
            tolist={this.state.list}
            onChange={this.listChange}
          />

最后在方法的部分做处理即可,完整代码如下:

import ReactDOM from "react-dom";
import React from "react";
import "./index.css";

class List extends React.Component {
  constructor(props) {
    super(props);
    this.delList = this.delList.bind(this);
  }
  delList(e) {
    let index = e.target.getAttribute("data-id");
    this.props.onChange(index);
  }
  render() {
    return this.props.tolist.map((li, index) => {
      return (
        <li key={index}>
          {li}
          <span onClick={this.delList} data-id={index}>
            x
          </span>
        </li>
      );
    });
  }
}

class Todos extends React.Component {
  constructor(props) {
    super(props);
    this.listChange = this.listChange.bind(this);
  }
  state = {
    item: "xxx",
    list: [1, 2, 3],
    targetValue:'work'
  };

  listChange(index) {
    let cur = this.state.list;
    cur.splice(index, 1);
    this.setState({ list: cur });
  }

  addItem(){
    let value = this.state.targetValue;
    let newlist = this.state.list
    newlist.push(value)
    this.setState({list:newlist})
  }

  getValue(e){
    this.setState({targetValue:e.target.value})
  }

  render() {
    return (
      <div>
        <input type='text' value={this.state.targetValue} onChange={this.getValue.bind(this)}/><button onClick={this.addItem.bind(this)}>确定</button>
        <ul>
          <List
            additem={this.state.item}
            tolist={this.state.list}
            onChange={this.listChange}
          />
        </ul>
      </div>
    );
  }
}

ReactDOM.render(<Todos />, document.getElementById("root"));
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容