6/14 Storybook const Template = (args) => <Button {...args} />;について
const Template = (args) => <Button {...args} />;
がよくわからなかったので調べました
まずそれぞれの関係性の把握から
StorybookとTemplate関数、そしてButtonコンポーネントの関係を示す図
- Storybookは、異なる状態を表現するための
args
をTemplate関数に提供します。 - Template関数は、これらの
args
をプロパティとしてButtonコンポーネントに渡します。 - Buttonコンポーネントは、特定のプロパティでレンダリングされ、その結果がStorybookで視覚的に表現されます。
ここの関係性のイメージを持っていないと、コードを読んでいても、今ひとつ腑に落ちなかった私です。
コードでの例として
Buttonコンポーネントがcolor
とsize
という2つのプロパティを持っているとします。Storybookを使用して、これらのプロパティの異なる組み合わせを視覚的に確認したいと思います。
// Buttonコンポーネントの定義 const Button = ({ color, size }) => <button style={{ color, fontSize: size }}>Click me</button>; // Template関数の定義 const Template = (args) => <Button {...args} />; // Storybookのストーリー export const LargeBlueButton = Template.bind({}); LargeBlueButton.args = { color: 'blue', size: '20px' }; export const SmallRedButton = Template.bind({}); SmallRedButton.args = { color: 'red', size: '10px' };
LargeBlueButton
とSmallRedButton
という2つのストーリーを作成しています。
Template.bind({})は何をしているのか?
Template.bind({})
はJavaScriptのbind
メソッドを使用しています。bind
メソッドは、関数に特定のthis
値と前置引数を設定した新しい関数を作成します。
Storybookのコンテキストでは、Template.bind({})
は新しい関数を作成しますが、this
値は空のオブジェクト({}
)に設定されます。これは、Storybookが各ストーリーに対して新しい関数インスタンスを作成することを保証します。これにより、各ストーリーが独立して動作し、他のストーリーに影響を与えることなくargs
を変更できます。
const Template = (args) => <Button {...args} />; export const LargeBlueButton = Template.bind({}); LargeBlueButton.args = { color: 'blue', size: '20px' };
Template.bind({})
を呼び出すと、Template
関数の新しいインスタンスが作成されます。- この新しい関数は、
Template
関数と全く同じ動作をしますが、this
値が空のオブジェクト({}
)に設定されています。 - この新しい関数に
args
プロパティを設定すると、それらのargs
は新しい関数の呼び出しに使用されます。
独立したTemplateを生成して、argsの内容も変えられるようにするためにあるようです。