跟着做react项目(至P57)

后台的API接口在此文件,根据后台定义可知请求路径
在这里插入图片描述

在这里插入图片描述

每一列固定内容的列表(antd)
关于render的参数
在这里插入图片描述

后面自己验证一下这三个参数,不知道text和record的区别。
在这里插入图片描述
发现text和record完全相同,

console.log(text === record)

render: (text , record, index) => (
  <span>
        <button onClick={() => this.print(text, record, index)}>查看</button>

结果:前提是该列没有设置dataIndex,所以找不到对应的对象属性,text参数直接是整个对象
在这里插入图片描述
如果该列设置了dataIndex: ‘name’,则text就是对象的name属性值。而record是整个对象

console.log(text, record)

在这里插入图片描述

设置Table组件的rowKey=’_id’属性
在这里插入图片描述

注意,在 label 对应的 Form.Item 上不要在指定 name 属性,这个 Item 只作为布局作用。
复杂的控件(antd)
在这里插入图片描述


Category路由组件

怎么完成一个复杂多功能的组件,按常用的步骤和需求。

静态页面

知识概要:

dataSource数据直接是请求得到的数组,数组元素以对象形式展示类别信息。

columns会根据dataIndex决定对象哪些属性展示到table中。

之前的对话框Modal是以按钮触发函数,函数内部的使用 confirm() 可以快捷地弹出确认框。这里使用Modal组件标签,其中由属性visible来决定是否显示

<Card title={title} extra={extra}>
    <Table bordered
        rowKey='_id'
        dataSource={parent === '0' ? categorys : subCategorys}
        columns={this.columns}
        loading={loading}
        pagination={{ pageSize: 5, showQuickJumper: true, showSizeChanger: true }}
    />
    <Modal title="添加分类" visible={showStatus === 1}>
        <AddForm />
    </Modal>

    <Modal title="修改分类" visible={showStatus === 2}>
        <UpdateForm />
    </Modal>
</Card>

columns

this.columns = [
    {
        title: '分类名称',
        dataIndex: 'name'
    },
    {
        title: '操作',
        width: 300, //该列的宽度
        render: (category) => (
            <span>
                <LinkButton onClick={() => this.showUpdate(category)}>修改分类</LinkButton>
                {this.state.parentId === '0' ? <LinkButton onClick={() => this.showSubCates(category)}>
                    查看子分类</LinkButton> : null}
            </span>
        )
    }];

定义控制变量static

state = {
    categorys: [], // 一级分类列表
    subCategorys: [], // 二级分类列表
    parentId: '0', // 父分类的ID 用来查询二级分类
    parentName: '', // 父分类的名称
    loading: false, // 标识Table是否加载中
    showStatus: 0, // 是否显示Modal,0:不显示 1:添加框 2:更新框
}

获取数据

1.根据 parentId 异步获取分类列表显示

getCategorys = async (parentId) => {
    const result = await reqCategorys(parentId)
    if (result.status === 0) {
        const categorys = result.data
        if (parentId === '0') {
            this.setState({categorys})
        } else {
            this.setState({subCategorys: categorys})
        }
    } else {
        message.error('获取列表失败')
    }
}

2.显示指定分类的子分类列表

showSubCates = (category) => {
    this.setState({ parentId: category._id, parentName: category.name }, () => {
        // 在状态更新之后执行, 在回调函数中能得到最新的状态数据
        this.getCategorys()
    })
}

3.由展示二级列表转为一级列表

transToCates = () => {
    // 因为类中还存储着一级列表的数据
    this.setState({
        parentId: '0',
        parentName: '',
        subCategorys: [],
        showStatus: 0,
    })
}

4.显示修改的对话框——(输入框要显示原来的值)

showUpdate = (category) => {
     // 输入框要显示原来的值, 保存在class里面
     this.category = category
     this.setState({ showStatus: 2 })
 }
<LinkButton onClick={() => this.showUpdate(category)}>修改分类</LinkButton>

5.传给子组件当前category信息,子组件才知道修改哪个分类对象。
得到子组件里面的Form信息,这样才能根据表单信息发生更新请求

<Modal title="修改分类" visible={showStatus === 2}
     onOk={this.reqUpdateCategory}
     onCancel={() => {
         this.setState({ showStatus: 0 })
         // this.form.current.resetFields()
     }}
     destroyOnClose={true}
>
     <UpdateForm
         categoryName={category.name}
         setForm={form => this.form = form}
     />
</Modal>

6.发送添加分类的请求 (修改分类请求类似)

addCategory = () => {
     this.form.current.validateFields().then(async (values) => {
         this.setState({ showStatus: 0 })
         const { parentId, categoryName } = values

         const result = await reqAddCategory(categoryName, parentId)
         if (result.status === 0) {
             //添加的分类属于当前页面展示的分类
             if (parentId === this.state.parentId) {
                 this.getCategorys()
             } else if (parentId === '0') {
                 // 在二级分类列表下添加一级分类, 因为由二级分类返回一级分类不用查询数据库
                 this.getCategorys('0')
             }
         }
     }).catch((err) => {
         message.info('请输入分类名称')
     })
 }

知识点一:
情景:通过State对象的属性来控制查询的父级 / 子级 分类列表。但setState函数此时为异步更新。后果:调用查询分类列表的函数时,state.parentId还是为0,(表示查询父级列表)
而render()时,state.paretId就改变(表示显示子级列表)
在这里插入图片描述

查阅react文档——setState()

将 setState() 视为请求而不是立即更新组件的命令。为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。

setState() 并不总是立即更新组件。它会批量推迟更新。这使得在调用 setState() 后立即读取 this.state 成为了隐患。为了消除隐患,请使用 componentDidUpdate 或者 setState 的回调函数(setState(updater, callback)),这两种方式都可以保证在应用更新后触发。如需基于之前的 state 来设置当前的 state,请阅读下述关于参数 updater 的内容。

知识点二:
参考链接一
参考链接二
参考链接三

视频讲到的情景:如果你不修改Form的输入框,每次点击不同的分类列表对应的修改分类按钮,Form都会初始化不同的相应值。如果修改了Form的输入框,点击Modal组件的确认和取消按钮,下次点击修改分类按钮,Form会保持上一次修改的Input表单的值。

方法一 (不行):
点击确认或者取消按钮的回调事件里,都清除表单数据
this.form.current.resetFields()

第一次点击名称A的修改分类时,会正确读取;再次点击名称B的修改分类时,依然得到的是上一次点击的名称A的缓存,当再次点击名称B时——即滞后一次

方法二:
<Modal destroyOnClose={true} >关闭时销毁 Modal 里的子元素

知识点三:

  1. 如何向回调函数传递参数

点击按钮就会执行箭头函数,箭头函数再去执行带实参的回调函数

onClick={() => this.showSubCates(category)
  1. 子组件如何向父组件传递参数

父组件给子组件一个函数,由子组件执行传递实参,但赋值的是父组件的this

 <UpdateForm setForm={form => this.form = form} />
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值