antd表单组件报错 Cannot read property ‘setFieldsValue‘ of null

今天在用React的UI库Antd 4.x版本 里的表单和表格配合写一个修改的需求,由于每次点击修改要拿到原来的值,所以需要用到表单的一些Api

表单设置值的API

//表单
<Form ref={this.formRef}>
            <Item name="categoryName" label="分类名" hasFeedback rules={[{ required: true, message: '分类名不可以为空!' }]}>
              <Input allowClear placeholder="请输入分类名!" onChange={this.addonChange} />
            </Item>
          </Form>
  //相关API
 this.formRef.current.setFieldsValue({
        categoryName: name,//categoryName是对应的表单中Item的name字段 这里的name是方法拿到的变量
      })

表单清空值的API

this.formRef.current.resetFields()  //清空

报错 Uncaught TypeError: Cannot read property ‘setFieldsValue’ of null

报错原因:对话框模块还没显示,也就是表单还没挂载就调用了setFieldsValue,所以报错

附成功的源码

//列表页面
import React, { Component } from 'react'
import { Button, message, Table } from 'antd'
import { PlusCircleOutlined } from '@ant-design/icons'
import './css.less'
import { reqCategory } from '../../api'
import Modal from './components/Modal/view'
export default class CategoryComponent extends Component {
  formRef = React.createRef()
  constructor(props) {
    super(props)
    this.state = {
      dataSource: [],
      pageNumber: 1,
      pageSize: 5,
      isModalVisible: false,
      modalType: '',
      categoryId: 0,
    }
  }
  componentWillMount() {
    this.getListData()
  }
  componentWillUpdate(nextProps, nexpState) {
    let { isModalVisible } = this.state
    if (isModalVisible !== nexpState.isModalVisible) {
      this.getListData()
    }
  }
  getListData = async () => {
    let result = await reqCategory()
    if (result) {
      let { status, data, msg } = result
      if (status !== 0) message.error(msg, 1)
      this.setState({
        dataSource: data,
      })
    }
  }
  render() {
    let { dataSource, pageNumber, pageSize } = this.state
    return (
      <div style={{ width: '100%' }}>
        <div className={'categoryHeader'}>
          <Button style={{ float: 'right' }} type={'primary'} icon={<PlusCircleOutlined />} onClick={() => this.oppModal('新增')}>
            添加
          </Button>
          <div style={{ clear: 'both' }} />
        </div>
        <div className={'categoryBottom'}>
          <Table
            bordered
            rowKey="_id"
            dataSource={dataSource}
            columns={[
              {
                title: <span style={{ fontWeight: 700 }}>分类名</span>,
                dataIndex: 'name',
                align: 'left',
                key: '_id',
              },
              {
                title: <span style={{ fontWeight: 700 }}>操作</span>,
                key: '_id',
                align: 'center',
                width: '20%',
                render: reload => {
                  return (
                    <Button type={'link'} onClick={() => this.oppModal('修改', reload)}>
                      修改分类
                    </Button>
                  )
                },
              },
            ]}
            pagination={{
              current: pageNumber,
              pageSize: pageSize,
              showQuickJumper: true,
              onChange: this.onPageChange,
            }}
          />
        </div>
        {this.showModal(this.state.isModalVisible, dataSource)}
      </div>
    )
  }
  onPageChange = (pageNumber, pageSize) => {
    this.setState({
      pageNumber,
      pageSize,
    })
  }

  oppModal = (type, data) => {
    if (data) {
      let { _id, name } = data
      this.setState({
        isModalVisible: true,
        categoryId: _id,
        categoryName: name,
        modalType: type,
      })
    } else {
      this.setState({
        isModalVisible: true,
        modalType: type,
        categoryName: undefined,
      })
    }
  }
  closeModal = () => {
    this.setState({
      isModalVisible: false,
    })
  }
  showModal = (flag, data) => {
    let { categoryId, categoryName, modalType } = this.state
    if (flag) {
      return (
        <Modal flag={flag} dataSource={data} dataSourceFun={value => this.setState({ dataSource: value })} closeModal={() => this.closeModal()} id={categoryId} name={categoryName} type={modalType} />
      )
    }
  }
}

将对话框表单封装成独立的组件即可避免报错

//对话框表单组件
import React, { Component } from 'react'
import { Modal, Input, Form, message } from 'antd'
import { reqAddCategory, reqPutCategory } from '../../../../api'
const { Item } = Form

export default class ModalComponent extends Component {
  formRef = React.createRef()
  constructor(props) {
    super(props)
    this.state = {
      flag: false,
      type: '',
      id: 0,
    }
  }
  componentWillMount() {
    let { flag, id, name, type, dataSource } = this.props
    this.setState({
      flag,
      id,
      name,
      type,
      dataSource,
    })
  }
  componentDidMount() {
    let { name } = this.state
    this.formRef.current.setFieldsValue({ name })
  }
  closeClear = () => {
    let { closeModal } = this.props
    this.formRef.current.resetFields() //清空表单
    closeModal()
  }

  render() {
    let { flag, type } = this.state
    return (
      <Modal title={type} visible={flag} onOk={this.handleOk} onCancel={() => this.closeClear()} cancelText="取消" okText="确定">
        <Form ref={this.formRef}>
          <Item name="name" label="分类名" hasFeedback rules={[{ required: true, message: '分类名不可以为空!' }]}>
            <Input allowClear placeholder="请输入分类名!" onChange={this.addonChange} />
          </Item>
        </Form>
      </Modal>
    )
  }
  addonChange = e => {
    this.setState({
      name: e.target.value,
    })
  }

  handleOk = async () => {
    let { closeModal, dataSourceFun } = this.props
    let { type, dataSource, name, id } = this.state
    if (type === '新增') {
      if (!name) return message.info('分类名称不可以为空!')
      let result = await reqAddCategory(name)
      let { status, data, msg } = result
      if (status !== 0) {
        return message.error(msg, 1)
      } else {
        message.success('添加分类成功!', 1)
        let newDataSource = [...dataSource]
        newDataSource.unshift(data)
        dataSourceFun(newDataSource)
        this.formRef.current.setFieldsValue({ name: undefined }) //给表单设置值
        this.formRef.current.resetFields() //清空表单
      }
      closeModal()
    }
    if (type === '修改') {
      if (!name) return message.info('分类名称不可以为空!')
      let result = await reqPutCategory(id, name)
      let { status, msg } = result
      if (status !== 0) {
        return message.error(msg, 1)
      } else {
        message.success('修改分类成功!', 1)
        let newDataSource = [...dataSource]
        newDataSource.unshift({ _id: id, name: name })
        dataSourceFun(newDataSource)
        this.formRef.current.setFieldsValue({ name: undefined }) //给表单设置值
        this.formRef.current.resetFields() //清空表单
      }
      closeModal()
    }
  }
}

这个报错通常是由于在配置路由时引入的组件文件为空导致的。请仔细检查你的路由配置文件,确保你正确引入了组件文件,并且组件文件中有有效的内容。如果你确定你的路由配置和组件文件都没有问题,那么可能是由于安装的依赖版本不匹配造成的冲突。你可以使用指定版本号的方式重新安装相关依赖,例如使用以下命令安装react-app-rewired: ```npm install react-app-rewired@1.5.2 --save-dev``` 然后使用以下命令安装react-router-dom: ```npm install --save react-router-dom``` 记得在containers文件夹中创建register文件夹,并在register文件夹中创建register.jsx文件用于注册路由组件。这样应该可以解决你遇到的报错。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [搭建react项目遇到的问题2022](https://blog.csdn.net/lydxwj/article/details/127839373)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [React直聘项目(一):客户端基本配置](https://blog.csdn.net/weixin_51504662/article/details/123001016)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值