记录工作中犯的一些错......

293 阅读1分钟

错误使用antd的form表单中的initialValue属性导致的问题。

场景还原

在某个场景中需要点击按钮打开一个弹窗, 弹窗内容为一个表单, 表单某一项是获取的点击按钮前选中的某项数据。

代码还原

index.tsx

import * as React from 'react';
import { Button } from 'antd';
import { useModalData } from './index.hooks';
import ModalTest from './ModalTest';
export default function Demo() {
  const { show, handleClick, selectData, handleChange, closeModal } = useModalData();

  const generateList = () => {
    const list = ['test-id', 'group-id', 'program-id', 'menu-id'];
    return (
      <div>
        {list.map(item => {
          return (
            <Button onClick={() => handleChange(item)} key={item}>
              {item}
            </Button>
          );
        })}
      </div>
    );
  };

  return (
    <>
      <Button onClick={handleClick}>打开弹窗</Button>
      {generateList()}

      <ModalTest show={show} selectData={selectData} closeModal={closeModal} />
    </>
  );
}

index.hooks.ts

import  React  from 'react';
export const useModalData = () => {
  const [show, setShow] = React.useState(false);

  const handleClick = () => {
    console.log(selectData)
    setShow(true);
  }

  const [selectData, setSelectData] =  React.useState('test-id');

  const handleChange = (value:string) => {
    console.log(value)
    setSelectData(value)
  }

  const closeModal = () => {
    setShow(false);
  }


  return { show , handleClick , selectData, handleChange, closeModal }
}

ModalTest.tsx

import * as React from 'react';
import { Modal, Form, Input } from 'antd';

const ModalTest = (props: any) => {
  return (
    <Modal
      maskClosable={false}
      title="Basic Modal"
      visible={props.show}
      onCancel={props.closeModal}
    >
      <Form>
        <Form.Item name="test_id" label="测试" initialValue={props.selectData}>
          <Input readOnly={true} />
        </Form.Item>
      </Form>
    </Modal>
  );
};

export default ModalTest;


效果图

屏幕录制2021-08-04 下午6.09.29.gif

可以看到第二次点击后弹窗里内容还是显示的上一次的值。查了下antd官网后发现问题原因是该属性只在初始化以及重置时生效。

两种方法解决:

  1. ModalTest中的useEffect中使用FormsetFields方法(或者setFieldsValue)并且移除initalValue
const ModalTest = (props: any) => {
  const [form] = useForm();

//添加 useEffect
  React.useEffect(() => {
    props.show &&
      // form.setFieldsValue({ test_id: props.selectData });
      form.setFields([
        {
          name: 'test_id',
          value: props.selectData,
        },
      ]);
  }, [props.selectData, props.show]);
  return (
    <Modal
      maskClosable={false}
      title="Basic Modal"
      visible={props.show}
      onCancel={props.closeModal}
    >
      <Form form={form}>
      //移除 initalValue
        <Form.Item name="test_id" label="测试">
          <Input readOnly={true} />
        </Form.Item>
      </Form>
    </Modal>
  );
};

  1. ModalTest中的useEffect中使用FormresetFields方法。
const ModalTest = (props: any) => {
  const [form] = useForm();

//添加 useEffect
  React.useEffect(() => {
     props.show && form.resetFields();
  }, [props.show]);
  return (
    <Modal
      maskClosable={false}
      title="Basic Modal"
      visible={props.show}
      onCancel={props.closeModal}
    >
      <Form form={form}>
        <Form.Item name="test_id" label="测试" initialValue={props.selectData}>
          <Input readOnly={true} />
        </Form.Item>
      </Form>
    </Modal>
  );
};

修复后效果:

屏幕录制2021-08-04 下午6.37.38.gif

总结: 虽然是一个很简单的问题, 但是还是因为在工作中粗心导致出现了这样的bug, 在代码复审中被leader的火眼金晴抓了出来。故以此文记录, 希望以后的我能更加的仔细, 认真。