React의 한 위치에 모든 UI 구성 요소를 배치하려고 시도한 적이 있습니까?

React의 세계를 처음 접하는 경우 아마 그렇지 않을 것입니다.

그게 무슨 뜻이야?

참조 반응 아름다운 dnd 예.

예제에서 본 것을 이야기라고 합니다. 그리고 이야기를 만드는 데 사용되는 도구를 Storybook이라고 합니다.

이제 이 기사에서 이야기할 내용을 이해하셨을 것입니다. 고민하지 않고 탐색합시다.

스토리북이란?

Storybook은 구성 요소에 대한 놀이터를 제공하는 사용자 인터페이스 격리 개발 환경입니다. 기본 앱을 실행하지 않고도 다양한 방식으로 구성 요소를 사용할 수 있습니다. 설정을 통해 해당 포트에서 스토리북을 실행할 수 있습니다.

React에만 국한되지 않습니다. 우리는 Vue, Angular, Mithril, Marko, Svelte 등과 같은 대부분의 프론트엔드 프레임워크와 함께 스토리북을 사용할 수 있습니다.

스토리북에 대한 자세한 내용을 확인할 수 있습니다. 여기.

이야기란 무엇입니까?

스토리는 구성 요소의 렌더링 상태를 정의합니다. 공통 구성 요소를 사용하면 소품과 함께 다른 방식으로 사용할 수 있습니다. 각 상태에 대한 이야기를 작성할 수 있습니다.

Button 구성 요소가 있다고 가정해 보겠습니다.

버튼은 비활성화됨, 로드 중, 기본, 보조, 작음, 큼, 중간 등과 같은 다양한 상태로 존재할 수 있습니다. 모든 상태를 나열하면 자습서를 진행하기가 매우 어려울 것입니다. 나는 당신이 그것을 이해한다고 생각합니다. 스토리북 작업을 시작하면 더 많은 것을 얻을 수 있습니다.

다양한 케이스(Large, Medium, Small)의 버튼 스토리를 보실 수 있습니다.

프로젝트에서 스토리북 설정

우리는 반응 프로젝트에 스토리북을 설정할 것입니다.

갑시다.

  • 다음 명령으로 반응 프로젝트를 생성합니다. 원하는 대로 이름을 지정할 수 있습니다.
npx create-react-app storybook-demo
  • 이제 다음 명령을 사용하여 프로젝트에 스토리북을 설치합니다.
npx sb init

스토리북 설정을 완료했습니다.

스토리북은 우리에게 별도의 서버를 제공합니다.

시작하는 방법?

스토리북은 자동으로 스크립트 파일에 명령을 추가합니다. 스크립트 섹션 내의 package.json 파일에서 확인할 수 있습니다. 당분간 다음 명령을 실행하여 storybook 서버를 시작합니다.

npm run storybook

Storybook은 package.json 파일의 스크립트 섹션에 지정된 포트로 새 서버를 시작합니다. 기본 브라우저(반응 서버와 동일)에서 스토리북을 자동으로 엽니다.

기본적으로 다른 이야기를 볼 수 있습니다. 원하지 않는 경우 제거하거나 참조용으로 보관할 수 있습니다. 이전 섹션에서 논의한 것처럼 버튼은 여러 상태를 가질 수 있으며 스토리북에서 볼 수 있습니다(모든 상태가 언급된 것은 아님). 이 튜토리얼의 마지막 섹션에서 버튼에 대한 많은 스토리 세트를 작성할 것입니다.

동화책의 다른 섹션을 탐색하고 다른 섹션에 익숙해지십시오. 튜토리얼에서 그 중 몇 가지를 다룰 것입니다.

첫 번째 이야기를 작성해 봅시다.

테스트 스토리북

우리는 동화책이 실행되는 것을 보았고 그 안에 몇 가지 예가 있습니다.

  • src 폴더 안에 Button이라는 폴더를 만듭니다.
  • Button.jsx, Button.css 및 constants.js라는 파일을 만듭니다.
  • 아래 스니펫의 해당 코드를 파일에 배치합니다.

버튼.jsx

import React, { Component } from "react";
import PropTypes from "prop-types";

import "./Button.css";

import { buttonTypes, buttonVariants, buttonSizes } from "./constants";

class Button extends Component {
    static defaultProps = {
        isDisabled: false,
        type: "filled",
        variant: "oval",
        size: "medium",
        backgroundColor: "#1ea7fd",
        textColor: "#ffffff",
    };

    static buttonTypes = buttonTypes;
    static buttonVariants = buttonVariants;
    static buttonSizes = buttonSizes;

    renderButton = () => {
        const {
            text,
            isDisabled,
            type,
            variant,
            size,
            backgroundColor,
            textColor,
            onClick,
        } = this.props;
        return (
            <button
                onClick={onClick}
                className={`default ${variant} ${size} ${
                    isDisabled ? "disabled" : ""
                }`}
                style={
                    type === buttonTypes.outline
                        ? {
                              border: `1px solid ${backgroundColor}`,
                              color: "#000000",
                              backgroundColor: "transparent",
                          }
                        : {
                              backgroundColor: `${backgroundColor}`,
                              border: `1px solid ${backgroundColor}`,
                              color: textColor,
                          }
                }
                disabled={isDisabled}
            >
                {text}
            </button>
        );
    };

    render() {
        return this.renderButton();
    }
}

Button.propTypes = {
    text: PropTypes.string,
    isDisabled: PropTypes.bool,
    type: PropTypes.oneOf([buttonTypes.outline, buttonTypes.filled]),
    variant: PropTypes.oneOf([buttonVariants.oval, buttonVariants.rectangular]),
    size: PropTypes.oneOf([
        buttonSizes.small,
        buttonSizes.medium,
        buttonSizes.large,
    ]),
    backgroundColor: PropTypes.string,
    textColor: PropTypes.string,
    onClick: PropTypes.func,
};

export { Button };

버튼.css

.default {
    border: none;
    cursor: pointer;
    background-color: transparent;
}

.default:focus {
    outline: none;
}

.disabled {
    opacity: 0.75; 
    cursor: not-allowed;
}
.small {
    font-size: 12px;
    padding: 4px 8px;
}

.medium {
    font-size: 14px;
    padding: 8px 12px;
}

.large {
    font-size: 16px;
    padding: 12px 16px;
}

.oval {
    border-radius: 4px;
}

.rectangular {
    border-radius: 0;
}

상수.js

export const buttonTypes = {
    outline: "outline",
    filled: "filled",
};

export const buttonVariants = {
    oval: "oval",
    rectangular: "rectangular",
};

export const buttonSizes = {
    small: "small",
    medium: "medium",
    large: "large",
};

그 코드는 무엇입니까?

  Microsoft Office에서 클립보드 기록을 보는 방법

다양한 방식으로 사용할 수 있는 Button의 공통 구성 요소를 작성했습니다. 이제 다른 상태를 가질 수 있는 구성 요소가 있습니다.

아래 단계에 따라 첫 번째 이야기를 작성해 봅시다.

  • Button.stories.jsx라는 파일을 만듭니다.
  • React와 Button 구성 요소를 파일로 가져옵니다.
  • 이제 구성 요소 스토리의 제목이나 경로를 정의합니다. 다음 코드를 사용하여 정의합니다.
export default {
   title: ‘common/Button’,
}

위의 코드는 현재 파일에 있는 모든 스토리를 common/Button/ 디렉토리에 배치합니다.

  • 다음과 같이 필수 소품이 있는 버튼을 내보냅니다.
export const defaultButton = () => (
    <Button text=”Default Button” onClick={() => {}} />
);

첫 번째 이야기를 완성했습니다. 다음 명령으로 스토리북을 실행하고 출력을 확인합니다.

npm run storybook

우리는 더 많은 이야기를 쓸 것입니다. 결국 걱정하지 마십시오.

Frontend 개발에서 어떻게 유용합니까?

동화책을 사용하는 것의 주요 이점은 무엇입니까?

10명으로 구성된 팀에서 일하고 있다고 가정해 보겠습니다. 그리고 현재 작업 중인 프로젝트를 위해 모두가 작성한 공통 구성 요소를 확인해야 합니다.

어떻게 할 수 있습니까?

우리는 그것들을 확인하기 위해 모든 공통 구성 요소로 이동해야 합니다. 하지만 시간이 많이 걸리고 우리가 선호하는 방법은 아닙니다. 여기에 우리의 새로운 게스트 스토리북이 있습니다.

우리의 문제를 극복하기 위해 그것을 어떻게 활용합니까?

스토리북을 사용하여 공통 구성 요소(모든 UI 구성 요소)에 대한 스토리를 작성할 수 있습니다. 그리고 팀원이 다른 사람의 공통 구성 요소를 확인하고 싶을 때마다 스토리북 서버를 실행하기만 하면 위에서 본 것처럼 모든 UI 구성 요소가 표시됩니다.

스토리북의 렌더링된 구성 요소로 더 많은 작업을 수행할 수 있습니다. Storybook에는 스토리에 초능력을 부여하는 애드온이라는 개념이 있습니다.

스토리북 자체에서 UI 구성 요소의 응답성을 확인해야 한다고 가정해 보겠습니다. 스토리북에서 Viewport라는 애드온을 사용할 수 있습니다. 다음 섹션에서 애드온에 대해 자세히 알아볼 것입니다.

스토리북 작업

이 섹션에서는 공통 구성 요소인 Button의 다양한 상태를 정의하는 다양한 스토리를 작성할 것입니다.

이야기를 쓰는 것은 그리 어렵지 않습니다. 스토리는 구성 요소의 상태를 정의합니다. 구성 요소의 소품을 보면 구성 요소의 다양한 사용 사례를 쉽게 이해할 수 있습니다.

선택적 소품을 주어 몇 가지 이야기를 써 봅시다.

export const largeButton = () => (
    <Button text="Large Button" onClick={() => {}} size="large" />
);
export const outlineSmallButton = () => (
    <Button
        text="Outline Small Button"
        onClick={() => {}}
        size="small"
        type="outline"
    />
);
export const rectangularLargeButton = () => (
    <Button
        text="Rectangular Large Button"
        onClick={() => {}}
        size="large"
        variant="rectangular"
    />
);


export const disabledButton = () => (
    <Button text="Disabled Button" onClick={() => {}} isDisabled={true} />
);


export const warningButton = () => (
    <Button
        text="Warning Button"
        onClick={() => {}}
        backgroundColor="orange"
    />
);

위의 세 가지 스토리는 구성 요소 Button의 서로 다른 사용 사례를 정의합니다. 이제 공통 구성 요소에 대한 다른 사례를 추가할 차례입니다. disabledSamllRectangularButton, dangerButton, successDisabledButton 등을 추가해 보세요.

  2019년 최고의 Android용 이메일 클라이언트 8개

위의 경우에 대한 코드를 제공하지 않을 것입니다. 당신은 그것을 이해하기 위해 스스로 작성해야합니다. 지금까지 작성한 전체 스토리 코드를 볼 수 있습니다.

import React from "react";

import { Button } from "./Button";

export default {
    title: "src/common/Button",
};

export const defaultButton = () => (
    <Button text="Default Button" onClick={() => {}} />
);

export const largeButton = () => (
    <Button text="Large Button" onClick={() => {}} size="large" />
);

export const outlineSmallButton = () => (
    <Button
        text="Outline Small Button"
        onClick={() => {}}
        size="small"
        type="outline"
    />
);

export const rectangularLargeButton = () => (
    <Button
        text="Rectangular Large Button"
        onClick={() => {}}
        size="large"
        variant="rectangular"
    />
);

export const disabledButton = () => (
    <Button text="Disabled Button" onClick={() => {}} isDisabled={true} />
);

export const warningButton = () => (
    <Button
        text="Disabled Button"
        onClick={() => {}}
        backgroundColor="orange"
    />
);

이제 구성 요소에 대한 스토리 작성에 대해 완전히 파악했습니다.

애드온에 대해 알아보고 스토리를 강화하는 방법을 알아보는 다음 섹션으로 넘어가겠습니다.

스토리북 애드온

기본적으로 여러 애드온을 사용할 수 있습니다. 이 섹션에서는 개발에 가장 유용한 애드온을 탐색합니다.

버튼 스토리를 강화해 봅시다.

통제 수단

컨트롤은 스토리북 자체의 구성 요소에 사용자 지정 소품을 제공하는 기능을 추가합니다. Button 구성 요소의 경우 스토리북의 다양한 소품을 변경하는 컨트롤을 추가할 수 있습니다.

버튼 배경색에 가장 적합한 색상을 찾아야 한다고 가정해 보겠습니다. 구성 요소에 하나씩 주어 배경색을 확인하는 테스트를 하면 시간이 많이 걸립니다. 대신 스토리북에서 다른 색상을 선택할 수 있는 컨트롤을 추가할 수 있습니다. 스토리북 자체에서 배경색을 테스트할 수 있습니다.

Button 스토리에 컨트롤을 추가하는 방법을 살펴보겠습니다.

먼저 제목 아래의 모든 props를 다음과 같이 정의해야 합니다.

export default {
    title: "src/common/Button",
    argTypes: {
        text: { control: "text" },
        backgroundColor: { control: "color" },
        isDisabled: { control: "boolean" },
        size: {
            control: { type: "select", options: ["small", "medium", "large"] },
        },
        type: {
            control: { type: "select", options: ["filled", "outline"] },
        },
        variant: {
            control: { type: "select", options: ["oval", "rectangular"] },
        },
    },
};

다음으로 props를 구성 요소에서 분리하고 다음과 같이 args로 지정합니다.

export const outlineSmallButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
outlineSmallButton.args = {
    text: "Outline Small Button",
    size: "small",
    type: "outline",
};

구성요소 미리보기 창 하단에서 컨트롤을 볼 수 있습니다.

구성요소 미리보기 창 하단에서 컨트롤 탭을 볼 수 있습니다. 주변에서 놀아 라.

위와 같이 모든 스토리를 업데이트합니다. 이것은 동화책 애드온의 구문을 아는 것과 비슷합니다. argTypes에서 다양한 유형의 컨트롤을 사용했습니다. 스토리북에 있는 모든 컨트롤을 찾을 수 있습니다. 여기.

업데이트된 버튼 스토리는 다음과 같습니다.

import React from "react";

import { Button } from "./Button";

export default {
    title: "src/common/Button",
    argTypes: {
        text: { control: "text" },
        backgroundColor: { control: "color" },
        isDisabled: { control: "boolean" },
        size: {
            control: { type: "select", options: ["small", "medium", "large"] },
        },
        type: {
            control: { type: "select", options: ["filled", "outline"] },
        },
        variant: {
            control: { type: "select", options: ["oval", "rectangular"] },
        },
    },
};

export const defaultButton = (args) => <Button {...args} onClick={() => {}} />;
defaultButton.args = {
    text: "Default Button",
};

export const largeButton = (args) => (
    <Button {...args} onClick={() => {}} size="large" />
);
largeButton.args = {
    text: "Large Button",
};

export const outlineSmallButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
outlineSmallButton.args = {
    text: "Outline Small Button",
    size: "small",
    type: "outline",
};

export const rectangularLargeButton = (args) => (
    <Button {...args} onClick={() => {}} />
);
rectangularLargeButton.args = {
    text: "Rectangular Large Button",
    size: "large",
    variant: "rectangular",
};

export const disabledButton = (args) => <Button {...args} onClick={() => {}} />;
disabledButton.args = {
    text: "Disabled Button",
    isDisabled: true,
};

export const warningButton = (args) => <Button {...args} onClick={() => {}} />;
warningButton.args = {
    text: "Warning Button",
    backgroundColor: "orange",
};

행위

액션은 JavaScript의 이벤트입니다. JavaScript에서 이벤트인 버튼을 클릭할 수 있습니다. action addon을 사용하여 버튼 클릭에 대한 몇 가지 작업을 수행할 수 있습니다.

  초보자를 위한 Python 학습을 위한 12가지 리소스

조치를 통해 이벤트가 제대로 작동하는지 여부를 테스트할 수 있습니다. 비활성화된 버튼은 클릭할 수 없으며 활성화된 버튼은 클릭 가능해야 합니다. 조치를 사용하여 확인할 수 있습니다.

버튼 클릭에 동작을 추가하는 방법을 살펴보겠습니다.

이전에 onClick 소품에 익명 기능을 제공했습니다. 이제 업데이트를 해야 합니다.

  • 다음 명령문을 사용하여 storybook 애드온에서 작업을 가져옵니다.
import { action } from "@storybook/addon-actions";
  • 모든 () => {}를 다음 문으로 바꿉니다.
action("Button is clicked!")

이제 스토리북으로 이동하여 버튼을 클릭합니다. 컨트롤 탭 옆에 있는 작업 탭 아래에 메시지가 인쇄된 것을 볼 수 있습니다. 비활성화된 비활성화 버튼을 클릭하면 메시지가 인쇄되지 않습니다.

onChange, onMouseOver, onMouseOut 등과 같은 다양한 이벤트에 대한 작업을 사용하여 제대로 작동하는지 확인할 수 있습니다. 입력 요소에 대해 onChange에 대해 동일하게 구현해 보십시오.

작업에 대한 설명서를 참조하십시오. 여기.

배경

배경 애드온을 사용하여 미리보기 창의 배경을 변경할 수 있습니다. 코드를 작성할 필요가 없습니다. 스토리북 안에서 바꾸면 됩니다. 아래 gif를 볼 수 있습니다.

뷰포트

스토리북에서 구성 요소의 응답성을 테스트할 수도 있습니다. 뷰포트 옵션에 대해 알아보려면 아래 gif를 참조하십시오.

문서

docs 애드온을 사용하여 스토리북에 컴포넌트를 문서화할 수 있습니다. 팀으로 작업할 때 더 유용합니다. 구성 요소를 읽고 직접 이해할 것입니다. 개발자의 시간을 많이 절약해 줍니다.

스토리북의 구성요소 미리보기 창에서 캔버스 탭의 오른쪽 상단에 있는 문서를 볼 수 있습니다. 여기에는 구성 요소의 모든 스토리에 대한 모든 문서가 포함됩니다. 마크다운과 구성 요소 렌더링을 모두 포함하는 구성 요소에 대해 문서화하려면 Button.stories.mdx를 사용해야 합니다. 구성 요소 스토리와 함께 내부에 몇 가지 추가 마크다운 코드를 작성합니다.

우리는 우리의 이야기에 대한 문서를 작성하고 있습니다. 코드에는 마크다운 및 구성 요소 렌더링이 포함됩니다. 구문을 배우는 것뿐입니다. 당신은 첫눈에 그것을 얻을 것입니다.

Button.stories.mdx 문서 코드를 살펴보겠습니다.

<!--- Button.stories.mdx -->

import {
    Meta,
    Story,
    Preview,
    ArgsTable
} from '@storybook/addon-docs/blocks';

import { Button } from './Button';

<Meta title="MDX/Button" component={Button} />

# Button Documentation

With `MDX` we can define a story for `Button` right in the middle of our
Markdown documentation.

<ArgsTable of={Button} />

export const Template = (args) => <Button {...args} />

## Default Button
We can write the documentation related to the Default Button
<Preview>
    <Story name="Default Button" args={{
        text: 'Default Button'
    }}>
    {Template.bind({})}
   </Story>
</Preview>

## Large Button
We are writing sample docs for two stories, you can write rest of them
<Preview>
    <Story name="Large Button" args={{
        text: "Large Button",
        }}>
        {Template.bind({})}
    </Story>
</Preview>

문서화 구성 요소에 대해 자세히 알아보기 여기.

추가 기능에 대해 자세히 알아볼 수 있습니다. 여기.

결론

튜토리얼을 즐기고 스토리북에 대해 배웠기를 바랍니다. 그리고 팀에서 효과적으로 사용하여 작업을 생산적으로 만드십시오.

반응이 처음이신가요? 이 학습 리소스를 확인하십시오.

행복한 코딩 🙂