Essentials/Actions

김동현·2026년 3월 22일

액션 (Actions)

React | Vue | Angular | Web Components | 그 외(More)

'액션(Actions)'은 컴포넌트의 이벤트 핸들러(콜백 함수)가 제대로 호출되었는지 확인하고, 그때 어떤 인자(arguments)들이 전달되었는지 눈으로 직접 볼 수 있게 해주는 기능입니다. 액션 패널(actions panel)을 열어보면, 스토리의 args로 전달된 함수가 불렸을 때의 기록이나 기타 다른 함수 호출 내역들을 실시간으로 확인할 수 있어요.

비디오: 애드온 액션 데모 (Addon Actions Demo)

스토리 인자로 액션 사용하기 (Story args)

액션을 사용하려면, 스토리북이 특별히 만들어주는 '모의 함수(mock functions)'를 여러분 컴포넌트의 이벤트 핸들러 args에 쏙 넣어주면 됩니다. 이 액션 arg를 가져오는 방법에는 크게 두 가지가 있어요:

storybook/testfn 스파이 사용하기 (Via storybook/test fn spies)

액션을 작성하는 가장 추천하는 방법storybook/test 패키지에서 제공하는 fn 유틸리티를 사용하는 것입니다. 이 fn은 인자를 모킹(mock)하고 감시(spy)해 주는 똑똑한 함수라서, 특히 인터랙션 테스트(interaction tests)를 작성할 때 빛을 발합니다.

아래처럼 컴포넌트의 메서드(이벤트 핸들러) 값으로 fn() 함수를 할당해 주기만 하면 모킹이 끝납니다!

// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Meta } from '@storybook/your-framework';
 
import { fn } from 'storybook/test';
 
import { Button } from './Button';
 
const meta = {
  component: Button,
  // 👇 onClick arg를 감시(spy)하기 위해 `fn`을 사용합니다. 
  // 이제 버튼을 클릭하면 액션 패널에 짠! 하고 나타날 거예요.
  args: { onClick: fn() },
} satisfies Meta<typeof Button>;
 
export default meta;

이렇게 세팅해 두고, 사용자가 (혹은 play 함수가) 화면에서 컴포넌트와 상호작용하여 해당 arg가 호출되면, 그 찰나의 순간을 fn이 포착해서 아래 그림처럼 액션 패널에 기록해 줍니다:

Actions usage

자동으로 인자 매칭하기 (Automatically matching args)

또 다른 방법으로는, 특정 패턴에 맞는 모든 argTypes를 자동으로 액션으로 만들어버리는 전역 파라미터(global parameter)를 사용하는 방법이 있습니다.

아래 설정은 이름이 on으로 시작하는 모든 argType들에 대해 자동으로 액션을 생성해 줍니다. (이 argType들은 직접 수동으로 지정할 수도 있고, 스토리북이 알아서 척척 추론(inferred automatically)해 낼 수도 있어요.)

컴포넌트에 메서드(콜백)가 수십, 수백 개씩 있어서 일일이 fn()을 달아주기 너무 귀찮을 때 쓰면 참 좋은 방법입니다. 하지만 이 방법은 별로 추천하지 않습니다. 왜냐하면, 이렇게 자동으로 추론되어 만들어진 arg들은 나중에 play 함수 안에서 스파이(spy)로 사용할 수 없기 때문이에요. 만약 argTypesRegex를 사용하면서 동시에 play 함수로 테스트까지 돌리고 싶다면, 어차피 테스트할 함수들은 다시 fn 유틸리티로 일일이 정의해 주어야 한답니다.

// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Preview } from '@storybook/your-framework';
 
const preview: Preview = {
  parameters: {
    actions: { argTypesRegex: '^on.*' },
  },
};
 
export default preview;

혹시 "나는 on으로 시작하는 거 말고 내가 원하는 것만 딱 골라서 자동으로 매칭하고 싶어!" 하신다면, 개별 스토리에 argTypesRegex 파라미터를 살짝 추가해서 조절할 수 있습니다:

// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
 
import { Button } from './Button';
 
const meta = {
  component: Button,
  parameters: { actions: { argTypesRegex: '^on.*' } },
} satisfies Meta<typeof Button>;
 
export default meta;
type Story = StoryObj<typeof meta>;
 
export const ExperimentalFeatureStory: Story = {
  //👇 이 스토리에만 특별히 기존 상속받은 `stable` 태그 대신 `experimental` 태그를 달아줍니다.
  tags: ['!stable', 'experimental'],
};

이 기능을 켜면, 컴포넌트가 렌더링한 가장 바깥쪽 HTML 엘리먼트에 표준 HTML 이벤트 핸들러가 찰싹 달라붙습니다. 그리고 지정된 CSS 선택자(selector)에 해당하는 이벤트가 발생할 때마다 액션을 빵빵 터뜨려 주죠. 포맷은 <이벤트이름> <선택자> 형식을 씁니다. 선택자를 따로 안 적으면 모든 엘리먼트에 다 적용돼요.

스토리 외의 함수 호출 기록하기 (Non-story function calls)

스토리의 args로 전달된 함수가 아니더라도, 그냥 개발하다가 디버깅 목적으로 어떤 함수가 불렸는지 액션 패널에 띄워보고 싶을 때가 있죠? 그럴 때도 액션 패널을 유용하게 쓸 수 있습니다!

크게 두 가지 방법이 있는데요. storybook/test에서 가져온 spyOn을 쓰는 방법과, storybook/actions에서 가져온 action 함수를 직접 쓰는 방법입니다. 간단하게 로그만 찍고 싶다면 spyOn을 추천하고요, 좀 더 복잡하게 상황을 제어해야 한다면 action 함수를 직접 쓰는 것이 좋습니다.

storybook/testspyOn 사용하기 (Via storybook/test spyOn)

storybook/test에서 제공하는 모의(mocks) 객체나 스파이(spies)들은 원래 자동으로 액션 패널에 로깅되도록 설계되어 있어요. 그래서 함수 호출 내역을 패널에 띄우는 가장 심플한 방법은 바로 spyOn 유틸리티를 사용하는 겁니다! 스파이들은 기본 이름으로 패널에 나타나는데, 만약 이름을 내 맘대로 예쁘게 바꾸고 싶다면 뒤에 .mockName('내가원하는이름')을 살짝 붙여주면 끝이에요.

// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, svelte)
import type { Preview } from '@storybook/your-framework';
 
import { spyOn } from 'storybook/test';
 
const preview: Preview = {
  async beforeEach() {
    spyOn(console, 'log').mockName('console.log');
  },
};
 
export default preview;

action 함수 직접 사용하기 (Via the action function)

함수가 100번 호출되는데 내가 원하는 딱 1번의 조건일 때만 로그를 찍고 싶을 수도 있잖아요? 그럴 때는 spyOn의 기본 동작(전부 다 로깅하기)을 살짝 비틀어서 커스텀 구현(custom implementation)을 넣어주면 됩니다. storybook/actions에서 action 함수를 가져온 다음, 내가 원하는 조건(someCondition)이 맞을 때만 이 action 함수를 수동으로 호출하게 만드는 거죠.

// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, svelte)
import type { Preview } from '@storybook/your-framework';
 
import { action } from 'storybook/actions';
import { spyOn } from 'storybook/test';
 
const originalConsoleLog = console.log;
const preview: Preview = {
  async beforeEach() {
    spyOn(console, 'log')
      // 먼저 액션 패널에 무조건 다 찍히는 자동 로깅을 끕니다!
      .mockName('')
      // 그리고 내 맘대로 동작을 다시 정의합니다.
      .mockImplementation((...args) => {
        // 로그 메시지가 내가 원하는 조건에 맞는지 확인하고...
        if (someCondition(args)) {
          // 맞다면, 그때만 수동으로 액션 패널에 쾅! 찍어줍니다.
          action('console.log')(...args);
        }
 
        // 물론 원래 콘솔창에도 나와야 하니까 진짜 console.log도 마저 실행해 줍니다.
        originalConsoleLog(...args);
      });
  },
};
 
export default preview;

API

파라미터 (Parameters)

이 액션 기능은 스토리북의 파라미터(parameters) 영역 중 actions 네임스페이스 아래에 다음과 같은 옵션들을 추가합니다:

argTypesRegex

타입: string

여기에 적은 정규 표현식(regex) 패턴에 딱 들어맞는 이름을 가진 arg들에 대해 자동으로 액션을 생성해 줍니다. 하지만 앞서 자동으로 인자 매칭하기 섹션에서 설명했듯이, 이 방법은 치명적인 단점이 하나 있으니 사용하실 때 꼭 유의해 주세요!

disable

타입: boolean

액션 패널을 아예 화면에서 꺼버릴지 말지 결정합니다.

이 파라미터는 보통 전체 프로젝트 수준(전역)에서는 패널을 꺼두고(true), 필요한 특정 컴포넌트나 스토리 수준에서만 쏙쏙 골라서 켤 때(false) 아주 유용하게 쓰입니다.

expandLevel

타입: number

기본값: 1

액션 패널에 객체(object) 같은 복잡한 데이터가 넘어왔을 때, 이걸 처음에 몇 단계(depth) 깊이까지 쫙 펼쳐서(expanded) 보여줄지 결정합니다. 안쪽 깊숙이 있는 데이터까지 한눈에 바로 보고 싶을 때 숫자를 올려주시면 됩니다.

내보내기 (Exports)

이 애드온에서는 다음 함수를 가져다 쓸 수 있습니다:

import { action } from 'storybook/actions';

action

타입: (name?: string) => void

이 함수를 호출하면 나중에 클릭 이벤트 같은 게 발생했을 때 스토리북 UI의 액션 패널에 짠! 하고 나타나는 수동 액션을 만들 수 있습니다. 선택 사항으로 name 파라미터에 문자열을 넘겨주면, 나중에 액션 패널에서 이 액션을 식별할 때 그 이름표가 붙어서 나와요.


이 페이지가 유용했나요? 👍 👎
✍️ 깃허브에서 편집하기 (Edit on Github)

profile
프론트에_가까운_풀스택_개발자

0개의 댓글