初探React-App,开发一个待办事项

大熙哥 2021年07月17日 153次浏览

在此之前我已经使用vue-cli开发了几个小项目,有codeshare代码共享平台、C4智慧网络管理系统,对React一直都是未曾接触到状态,了解到vue-cli的开发规范很好奇React-App的目录结构又该是怎么样才不算是异类呢?

vue-cliv小熙开发规范

创建React-App

有手就行就不细嗦。

npm install -g create-react-app
create-react-app react-app
cd react-app
npm start

官方教程

目录结构

通过百度搜索,了解到一个完整react项目的目录结构,但是可能并不一定正确可能还存在个人风格,我还是按照此风格尝试开发。

Z:\USERDATA\XIAOXI_NEW\CODE\REACT\REACT-APP\SRC
│  App.css
│  App.js
│  App.test.js
│  index.css
│  index.js
│  reportWebVitals.js
│  setupTests.js
│
├─components
│  │  index.js
│  │
│  ├─TodoHeader
│  │      index.js
│  │
│  ├─TodoInput
│  │      index.js
│  │
│  └─TodoList
│          index.js
│          TodoItem.js
│
└─views
    │  index.js
    │
    └─Todo
            index.js

以上的结构主要是借用了以下的技术点:

  • 借助文件名为index时的特性。
  • 在Components下面的index.js中进行抛出。
  • 利用import引入文件和react创建class或者function来架接模块之间的链接
  • 集中在一个App.js文件上。

界面开发实战

待办事项界面

虽然这个界面很丑,但是运用了react的组件开发来进行的,从列表中的每一项,总列表,添加框,标题都是一个组件,在Todo进行一个整合,在App.js进行引用显示。

事项由父组件进行保存和控制,通过props传递内容。

import React, { Fragment, Component } from "react"
import { TodoHeader, TodoInput, TodoList } from "../../components"

export default class Todo extends Component {
    constructor(props) {
        super(props);
        this.state = {
          listData: ['刷前端面试题500道', '学习React', '去吃顿好的'],
        };
    }
    render() {
        return (
            <Fragment>
                <TodoHeader desc="React入门程序:待办事项"></TodoHeader>
                <TodoInput btnText="添加"></TodoInput>
                <TodoList listData={this.state.listData}></TodoList>
            </Fragment>
        )
    }
}

添加事项的功能

添加事项

首先输入框和添加按钮在一个子组件,子组件需要保存和管理输入框的内容,在构造器state添加inpValu变量,绑定输入框的onChange事件,注意的是此时需要使用bind改变this的作用域,否则this可能会是undefined,无法setState。添加按钮则需要把输入框的内容通过this.props.onClick传递给上级组件。

import React, { Component } from "react"

export default class TodoInput extends Component {
	constructor(props){
		super(props);
		this.state = {
			inpValu:''
		}
	}
	handelChange(e){
		this.setState({
			inpValu:e.target.value
		})
	}
    render() {
        return (
            <div>
                <input type="text" onChange={this.handelChange.bind(this)} defaultValue={this.state.inpValu}></input>
                <button onClick={() => this.props.onClick(this.state.inpValu)}>{this.props.btnText}</button>
            </div>
        )
    }
}

上级组件也定义onClick方法,通过onClick={(e) => this.handleClick(e)} ,自定义handleClick方法,官网推荐通过使用 .slice() 方法创建了数组的一个副本,而不是直接修改现有的数组。

不直接修改这种方式有以下几点好处:

  • 简化复杂的功能
  • 跟踪数据的改变
  • 确定在 React 中何时重新渲染
import React, { Fragment, Component } from "react"
import { TodoHeader, TodoInput, TodoList } from "../../components"

export default class Todo extends Component {
    constructor(props) {
        super(props);
        this.state = {
          listData: ['刷前端面试题500道', '学习React', '去吃顿好的'],
        };
    }
    handleClick(e) {
        const listData = this.state.listData.slice()
        listData.unshift(e)
        this.setState({listData: listData})
    }
    render() {
        return (
            <Fragment>
                <TodoHeader desc="React入门程序:待办事项"></TodoHeader>
                <TodoInput onClick={(e) => this.handleClick(e)} btnText="添加"></TodoInput>
                <TodoList listData={this.state.listData}></TodoList>
            </Fragment>
        )
    }
}

删除事项的功能

同理,删除事项的原理和上面差不多,但是删除按钮是三级深的组件。并且要考虑怎么知道删除哪一项,因此前面的代码要进行更改,把index数组下标也传入到具体每一项中,在点击删除按钮的时候就可以知道要删除哪一项。

首先在TodoItem组件调用this.props.onClick传递要删除的项目下标。

import React, { Component } from "react"
import './TodoItem.css'
export default class TodoItem extends Component {
    render() {
        return (
            <div className="item">
                <div>{this.props.item}</div>
                <button onClick={() => this.props.onClick(this.props.index)}>删除</button>
            </div>
        )
    }
}

然后在TodoList组件继续调用this.props.onClick继续向上传递要删除的项目下标。

import React, { Component } from "react"
import TodoItem from "./TodoItem"

export default class TodoList extends Component {
    render() {
        const listData = this.props.listData
        const listItems = listData.map((item, index) => (
          <TodoItem key={index} item={item} index={index} onClick={(e) => this.props.onClick(e)}></TodoItem>
        ))
        return (
            <div>
                {listItems}
            </div>
        )
    }
}

最终在Todo组件下,可以对数据进行删除操作。

import React, { Fragment, Component } from "react"
import { TodoHeader, TodoInput, TodoList } from "../../components"

export default class Todo extends Component {
    constructor(props) {
        super(props);
        this.state = {
          listData: ['刷前端面试题500道', '学习React', '去吃顿好的'],
        };
    }
    handleClick(e) {
        const listData = this.state.listData.slice()
        listData.unshift(e)
        this.setState({listData: listData})
    }
    deleteClick(e) {
        const listData = this.state.listData.slice()
        listData.splice(e,1)
        this.setState({listData: listData})
    }
    render() {
        return (
            <Fragment>
                <TodoHeader desc="React入门程序:待办事项"></TodoHeader>
                <TodoInput onClick={(e) => this.handleClick(e)} btnText="添加"></TodoInput>
                <TodoList onClick={(e) => this.deleteClick(e)} listData={this.state.listData}></TodoList>
            </Fragment>
        )
    }
}

删除操作测试

以上就完成了删除的操作,一个简单的待办事项做成了。通过这个小项目,学习了如何创建react脚手架、react的组件开发、如何管理数据、props的传递和调用,输入框的输入监听等知识点。

界面美化

界面美化后

美化主要是运用了css、flex布局。

以上就是文章全部内容啦,如果觉得还可以请为我留言和转发,感谢!