1F8 Blog

Ant Design - Modal

April 27, 2022

Learning Ant Design Components ~ Modal

I am learning about how Ant Design build their components, and I am hoping that at the end of this learning experience, I would be a better programmer.

Basic Component Structure

Task Specific Component structure example from ConfirmDialog

// any types and interfaces defined at the top
interfaces Foo extends BaseProp {}

// defining component itself
const Component = (props: Foo) {

  // destructure all props here even optional ones.
  const {
    okCancel,
    width,
    style
  } = props


  // Null checks, ternary, and setting default values done here
  const okCancel = 'okCancel' in props ? props.okCancel! : true;
  const width = props.width || 416;
  const style = props.style || {};
  ...


  // styling class name generated with prefix.
  const className = classNames(...)


  // Button component or any small component used in this component created here
  const cancelButton = <ActionButton>...</ActionButton>


  // combine imported and small components build within it here and returns the component
  return (...) 
}

Modal status handling

A modal has status like warn, info, success, and noramally each status has its own icon. Each status has its own method which returns props already merged with base props. example - ANT Design confirm

// Confirm modal
export default function confirm(config: ModalFuncProps) {
  let currentConfig = { ...config, close, visible: true } as any;
  ...
  // method for confirm defined here
  function destroy () {}
  function render () {}
  function update () {}

  return {
    destroy: close,
    update,
  };
}

// each success, warn and info gets its own method like this to generate props
export function withSuccess(props: ModalFuncProps): ModalFuncProps {
  return {
    icon: <CheckCircleOutlined />,
    okCancel: false,
    ...props,
    type: 'success',
  };
}

then uses it like this

Modal.success = function successFn(props: ModalFuncProps) {
  return confirm(withSuccess(props));
}

Other Interesting Findings

TypeScript null checks

This is about typescript, but I’ll add this here too. I’ve used ? null check for none method objects, somehow didn’t realize we could do this onCancel?.() on methods. I’ve gotten undefined when an object doesn’t have an optional proerty and try to use that in my code. Now I know 😃

code from ANT Design Modal

  const handleCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
    const { onCancel } = props;
    onCancel?.(e);
  };

Use of React useRef, forwardRef and useImperativeHandle for a component with different contexts/child elements

According to the react documentation, useRef gets DOM’s mutable vlaue and acts like a box with mutable value in it, and when you try to wrap a component with ref with another component, react doesn’t pass the ref to the child component since ref is not a prop, more like a key, so you need to use forwardRef to make sure it passes refs to the child components. useImperativeHandle is also used along with those refs to

ANT Design Modal component uses these concepts and passes methods and context references. I thought it was really interesting to see this piece of code

const ElementsHolder = React.memo(
  React.forwardRef<ElementsHolderRef>((_props, ref) => {
    const [elements, patchElement] = usePatchElement();
    React.useImperativeHandle(
      ref,
      () => ({
        patchElement,
      }),
      [],
    );
    return <>{elements}</>;
  }),
);

this function is exported out as contextHolder which is part of what we can use as a library user. ElementsHolder inserts children and when closed, it removed them. usePatchElement all it does is sets the child element and returns a method to remove.

  const [modal, contextHolder] = Modal.useModal();

  React.useEffect(() => {
    modal.confirm({
      // ...
    });
  }, []);

  return <div>{contextHolder}</div>;

It took me a while to understand this contextHolder part since it’s being passed around a lot. Once I understood what each piece of code was doing, I started to notice that each key component does one thing which is definitely how we want to structure our code. I will try to learn about Input component next.


「ネットショップを始めたいがサイト制作の知識がない」、「商品を国内外問わず販売したい」、「自社サイトを立ち上げたいがコストは極力抑えたい」といったお悩みを一挙に解決致します!

当社は、低コストで導入が可能・尚且つ決済手数料が低く、幅広い機能にも対応している世界NO.1のシェアのECサイトShopify認定パートナーで、Shopifyのストア構築や、埋め込みアプリの開発を行っております。

些細なことでも構いませんので、まずはお気軽にご相談ください。

A dinosaur

株式会社1F8

私たちはWebテクノロジー開発を通してお客様がビジネスに集中できる環境を創造します

Written by 1F8 ウェブ大工人 Twitterでフォローする

©1F8, 2020, Built with 💖