在此之前我已经使用vue-cli开发了几个小项目,有codeshare代码共享平台、C4智慧网络管理系统,对React一直都是未曾接触到状态,了解到vue-cli的开发规范很好奇React-App的目录结构又该是怎么样才不算是异类呢?
创建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布局。
以上就是文章全部内容啦,如果觉得还可以请为我留言和转发,感谢!