超级详细react笔记(十三)项目篇(待办事项)

0 使用技术

  • axios 请求数据
  • json-server 模拟数据
  • react 操作dom
  • element-ui

1 项目搭建

1.1 创建项目

  • 创建项目create-react-app tips 项目名称为tips
  • 启动项目npm start

在这里插入图片描述

1.2 搭建项目结构

1.2.1 准备数据

  • 使用json-server
  • 模拟数据
  • 测试数据json-server tips.json
    在这里插入图片描述

database/tips.json

{
    "todos":[
        {
            "id":1,
            "title":"吃饭",
            "status":false
        },
        {
            "id":2,
            "title":"睡觉",
            "status":true
        },
        {
            "id":3,
            "title":"上钟",
            "status":false
        },
        {
            "id":4,
            "title":"打豆",
            "status":true
        },
        {
            "id":5,
            "title":"上课",
            "status":true
        },
        {
            "id":6,
            "title":"哒哒",
            "status":true
        }
]
}

1.2.2 组件化开发

在这里插入图片描述

  • APP.js
import React,{Component} from 'react'
export default class APP extends Component{
    constructor() {
        super();
    }
    render() {
        return(
            <div>APP</div>
        )
    }
}

  • index.js
import React from 'react';
import ReactDOM from 'react-dom';
import APP from "./APP";

ReactDOM.render(
  <APP/>,
  document.getElementById('root')
);


在这里插入图片描述

1.2.3 引入element-ui

  • 下载依赖cnpm i element-react -S
  • 下载主题包cnpm i element-theme-default -S
  • 下载加载cnpm i react-hot-loader -S
  • 配置element-ui 在入口文件中引入import 'element-theme-default'
  • 重启项目npm start

2 开发模块

在这里插入图片描述

在这里插入图片描述

2.1 Header模块

  • 静态数据,可以使用无状态组件
import React from 'react'
export default function Header (prop){
    return(
        <div>
           <h1 style={{color:'skyblue'}}>{prop.title}</h1>
        </div>
    )
}

2.2 Input模块

import React,{Component} from 'react'
import {Input,Button} from 'element-react'
export default class TipInput extends Component{
    constructor() {
        super();
    }
    render() {
        return(
            <div>
                <Input style={{width:"30%"}} name='content' autoFocus/>
                <Button type='success' onClick={this.addItem}>{this.props.btn}</Button>
            </div>
        )
    }
    addItem=()=>{
        this.props.addItem(document.querySelector('input').value)
    }
}

2.3 List模块

import React,{Component} from 'react'
import {Card} from 'element-react'
import Item from "./tipItem";
export default class List extends Component{
    constructor() {
        super();
    }
    render() {
        return(
            <div>
                <Card className="box-card" style={{width:"30%",
                    marginTop:'20px'}}>
                    {
                        this.props.todos.map(el=>{
                            return  <Item key={el.id} {...el} myCheck={this.props.myCheck}/>
                        })
                    }
                </Card>
            </div>
        )
    }
}

2.4 Item模块

import React,{Component,Fragment} from 'react'
import {Card,Checkbox} from "element-react";
import classNames from 'classnames'
import './index.css'
export default class Item extends Component{
    constructor() {
        super();
        this.state={
           isShow:''
        }
    }
    componentWillReceiveProps(nextProps, nextContext) {
    }
    render() {
        return(
            <Fragment>
                <div className="text item" className={classNames({'span':this.props.status})}>
                    <Checkbox checked={this.props.status} onChange={this.changeCheck}/>
                    <span>{this.props.title}</span>    &nbsp;&nbsp;&nbsp;&nbsp;
                    <span >{this.props.status?'已完成':'未完成'}</span>
                </div>
            </Fragment>
        )
    }
    changeCheck=()=>{
        this.props.myCheck(this.props.id)
    }
}

3 项目文件

  • component/index.js
export {default as Header} from './tipHeader'
export {default as Input} from './tipInput'
export {default as List} from './tipList'
  • Api/index.js
import axios from "axios";
import React from 'react'
axios.defaults.baseURL='http://127.0.0.1:3000'
React.Component.prototype.$http = axios
  • APP.js
import React,{Component} from 'react'
import {Header,Input,List} from './component'
export default class APP extends Component{
    constructor() {
        super();
        this.state={
            title:'待办事项',
            btn:'添加',
            todos:[]
        }
    }
    componentDidMount() {
        this.getData()
    }
    render() {
        return(
            <div>
                <Header {...this.state}/>
                <Input {...this.state} addItem={this.addItem}/>
                <List {...this.state} myCheck={this.updateCheck}/>
            </div>
        )
    }
    async getData(){
        const res = await this.$http.get('/todos')
       this.setState({
           todos:res.data
       })
    }
    addItem=async title=>{
        const res = await this.$http.post('/todos',{
            id:new Date().getTime(),
            title,
            status:false
        })
        console.log(this.state.todos)
       await this.getData()
        this.setState({
            title:''
        })
    }
    updateCheck=id=>{
       this.setState(state=>{
           return({
               todos:state.todos.map(el=>{
                   if(el.id===id){
                       el.status=!el.status
                   }
                   return el
               })
           })
       })
    }
}

4 优化

4.1 条件渲染

4.1.1 旧版渲染

  componentWillReceiveProps(nextProps, nextContext) {
        this.setState({
            status:nextProps.status?'已完成':'未完成'
        })
    }

4.1.2 新版渲染

  • react 16.3以上
static getDerivedStateFromProps(props){
        return{
            status:props.status?'已完成':'未完成'
        }
    }

4.2 按需更新

4.2.1 利用生命周期

shouldComponentUpdate(nextProps, nextState, nextContext) {
        return this.props.status===! nextProps.status
    }

4.2.2 利用纯组件

export default class Item extends PureComponent

5 用户体验

在这里插入图片描述
在这里插入图片描述

6 总结

  • 1 掌握组件之间传值

  • 2 添加事项

    • 父组件定义添加事项方法,通过绑定传给子组件(Input)
    • 子组件通过参数的形式将值给父组件
    • 父组件得到值后进行业务处理
      • 不能通过push添加,可以concat
      • axios可以通过post(url,obj)
  • 3 添加事项值

    • 原生react
    • input 绑定ref-------this.inputRef=createRef()-----this.inputRef.current.value
    • element-ui
      • document.querySelector('input').value
  • 4 复选框选中

    • 父组件 将方法绑定给子组件
    • 子组件通过参数将id传给父组件
    • 父组件遍历,判断是否相等,取反
  • 5 优化 按需引入

    • pureComponent

    • shouldComponentUpdate()

      return this.props.status===! nextProps.status

  • 6 条件渲染

    • static getDerivedStateFromProps(props){
          return{
              status:props.status?'已完成':'未完成'
          }
      }
      

7 源码

码云地址:https://gitee.com/lakerzhang/tips.git

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值