美文网首页
使用react hooks 和 ant-design 遇到的问题

使用react hooks 和 ant-design 遇到的问题

作者: Joemoninni | 来源:发表于2020-10-16 14:07 被阅读0次

使用react hooks 和 ant-design 遇到的问题

功能介绍:实现登录,博客的增删改查

技术点: 前端使用react hooks编写函数式组件,create-react-app创建项目,使用ant-design,后端使用node.js原生实现

此文章只针对前端部分遇到的一些问题做一个记录,如有错误,请指出。

一、 ant-design:

  1. table样式问题:一定要给装table的容器设置一个高度100%,否则样式会出现奇奇怪怪的错误。

    正如博客列表需要表格来展示,这里把table放在一个容器里面,因为没有给容器设置高度100%,最后是这样的

    badTable.png

显然不是我们要的结果,只有给容器加上height:100%才能正常显示。

注意:1.当我们想要表格实现自适应时,必须给<Table />组件的tableLayout属性赋值为"fixed",如果是"auto",表格的宽度就无法填满容器。

​ 2. warning.png

这里报一个warning,他说每一个child在一个列表中应该有一个唯一的"key",在ant-design的官方文档中有一个注意点:

notice.png

这时加上<Table rowKey={record => record.id} />,就可以了。

  1. Popcomfirm气泡确认框

再一个就是删除某一行的操作,初始代码是这样的

... 省略的代码
export default function BlogList(props) {
    ... 省略的代码
    // 删除博客
    const deleteBlog = async (data) => {
        let id = data.id
        const result = await axios.post('http://localhost:5000/api/blog/del?id='+ id)
        if (result.data.data === 0) {
            message.success('Successfully delete!')
            props.getBlogList()
        } else {
            history.push('/login')
            message.error('Failure! Please login in first!')
        }
    }
    
    const columns = [
        {...}, {...}, // 省略,此处只写出关键代码
        {
            title: "Action",
            dataIndex: "action",
            key: "action",
            render: (text, record) => (
                <Space size="middle">
                    <Button type="ghost" icon={<EditOutlined />} onClick={() => onCreate(record)}>Edit</Button>
                    <Button type="ghost" icon={<DeleteOutlined />} onClick={() => deleteBlog(record)}>Delete</Button>
                </Space>
            )
        }
    ]
    
    return (
     <div style={{height: '100%'}}>
         <Table 
                 dataSource={props.list}
                columns={columns}
                rowKey={record => record.id}
                tableLayout="fixed"
                size="small"   
             ></Table>
        </div>
    )
} 

上述代码可以实现删除操作,但是一般来说要删除某一行,点击的时候应该还得有一个待确认的操作,确认删除或者取消删除,看antd文档,找到一个Popconfirm气泡确认框

修改代码:

... 省略的代码
export default function BlogList(props) {
    ... 省略的代码
    // 删除博客
    // const deleteBlog = async (data) => {
        // let id = data.id
        // const result = await axios.post('http://localhost:5000/api/blog/del?id='+ id)
        // if (result.data.data === 0) {
        //     message.success('Successfully delete!')
        //     props.getBlogList()
        // } else {
        //     history.push('/login')
        //     message.error('Failure! Please login in first!')
        // }
    // }
    
    // 确认删除博客
    const handleOnConfirm = async () => {
        // 2. 将原先deleteBlog事件的一系列操作复制到onConfirm事件中
        let id = data.id
        const result = await axios.post('http://localhost:5000/api/blog/del?id='+ id)
        if (result.data.data === 0) {
            message.success('Successfully delete!')
            props.getBlogList()
        } else {
            history.push('/login')
            message.error('Failure! Please login in first!')
        }
    }
    
    const columns = [
        {...}, {...}, // 省略,此处只写出关键代码
        {
            title: "Action",
            dataIndex: "action",
            key: "action",
            render: (text, record) => (
                <Space size="middle">
                    <Button type="ghost" icon={<EditOutlined />} onClick={() => onCreate(record)}>Edit</Button>
                    
                    // ----------- changed code -----------
                    <Popconfirm
                        title="Are you sure delete this task?"
                        onConfirm={handleOnConfirm} // 确认时的操作
                        onCancel={cancel} // 取消时的操作
                        okText="Yes"
                        cancelText="No"
                        >
                        <Button
                            type="ghost"
                            icon={<DeleteOutlined />}
                            // onClick={() => deleteBlog(record)} // 1.注释掉
                            >Delete</Button>
                    </Popconfirm>
                    // ----------- changed code -----------
                    
                </Space>
            )
        }
    ]
    
    return (
     <div style={{height: '100%'}}>
         <Table 
                 dataSource={props.list}
                columns={columns}
                rowKey={record => record.id}
                tableLayout="fixed"
                size="small"   
             ></Table>
        </div>
    )
} 

上述代码可以看到,我们想要的效果是分两步操作:

  1. 当我们点击Delete按钮的时候,弹出Popconfirm确认框
  2. 当我们点击确认框里面的确认按钮时,才进行发起删除请求的操作 或者 当我们点击取消时,取消删除操作

那我们就得

  1. 把Button的点击事件注释掉,然后deleteBlog这个事件已经没用了,

  2. 我们可以把它里面的操作放到onConfirm事件里面

  3. 这时有个问题,onComfirm里面需要获取id,也就是只有获取到当前行的内容,才能获取到该行的id

  4. 这时就得修改onComfrim操作了,不要返回一个handleOnConfirm函数,因为你如果是这样写,直接传参,那相当于是直接调用,页面加载完成后会马上把你所有的博客数据一条一条全删了

    onConfirm={handleOnConfirm(record)} // 如果直接传参数,会删除所有数据
    

    怎么解决?我们想要的是他延迟执行,而不是要他马上执行,这时我们就需要返回一个匿名函数。

    onConfirm={() => {handleOnConfirm(record)}}
    

补充一个注意点:我们是需要点击Button时,弹出确认框,所以我们要把Button放在Popconfirm里面。

相关文章

网友评论

      本文标题:使用react hooks 和 ant-design 遇到的问题

      本文链接:https://www.haomeiwen.com/subject/biuzpktx.html