Storybook: لا يمكن استخدام خطافات React مباشرة داخل قصة

تم إنشاؤها على ٢٢ فبراير ٢٠١٩  ·  53تعليقات  ·  مصدر: storybookjs/storybook

وصف الخطأ

لا يمكن استخدام الخطافات مباشرة في القصة ، فشل مع Hooks can only be called inside the body of a function component .

لإعادة إنتاج

رمز المثال:

import React from 'react'

import { storiesOf } from '@storybook/react'

const stories = storiesOf('Hooks test', module)

const TestComponent: React.FC = () => {
  const [state, setState] = React.useState(5)
  return (
    <button onClick={() => setState(state + 1)}>
      {state}
    </button>
  )
}

stories.add('this story works', () => <TestComponent />)

stories.add('this story fails', () => {
  const [state, setState] = React.useState(5)
  return (
    <button onClick={() => setState(state + 1)}>
      {state}
    </button>
  )
})

سلوك متوقع
القصة الأولى تعمل بشكل جيد ، القصة الثانية تفشل في التصيير الأولي

إصدارات
@storybook/[email protected]
[email protected]
[email protected]

react has workaround question / support

التعليق الأكثر فائدة

لقد واجهنا نفس المشكلة ، وهذا اختراق بسيط نقوم به لحلها.

stories.add('this story fails', () => React.createElement(() => {
  const [state, setState] = React.useState(5)
  return (
    <button onClick={() => setState(state + 1)}>
      {state}
    </button>
  )
}))

أوافق على أنه سيكون من الأفضل بكثير أن يتم دعمها محليًا دون اختراق. إذا وافق المشرفون أيضًا ، فربما يمكنني العثور على بعض الوقت للتوصل إلى PR 🙂.

ال 53 كومينتر

لست متأكدًا من أن هذا خطأ. أعتقد ، وقد أكون مخطئًا ، فإن الوسيطة الثانية لـ stories.add تتوقع أن تقوم دالة بإرجاع مكون وليس مكون React فعلي. حاول نقل مكون وظيفتك إلى الخارج ، يجب أن تحقق بعض النجاح ..

مثال

function SomeComponent() {
    const [blah] = React.useState('blah');
    return <div> {blah}</div>;
}
stories.add('BlahComponent', () => <SomeComponent />);

أعتقد ، وقد أكون مخطئًا ، فإن الوسيطة الثانية لـ stories.add تتوقع أن تقوم دالة بإرجاع مكون وليس مكون React فعلي.

لا ينبغي أن يكون AFAIK مهمًا حقًا ، لكن الأمر يستحق المحاولة دائمًا. أيضا ، sargant ما يلقي الخطأ؟ القصص القصيرة أم نظام الكتابة؟

Keraito لا أنا متأكد من أن الخطأ صحيح.

ذلك لأننا نستدعي الوظيفة خارج سياق التفاعل ، ويعرف أيضًا باسم Storybook أن الوظيفة كما يلي:

const element = storyFn();

ليس

const element = <StoryFn />

من المحتمل جدًا إذا بدأنا الأمر بهذه الطريقة ، فقد يعمل.

الآن نصيحةgabefromutah سليمة.

هذا هو السطر الفعلي للشفرة:
https://github.com/storybooks/storybook/blob/next/app/react/src/client/preview/render.js#L24

إذا أراد شخص ما أن يجرب هذا العمل ، فهذا هو المكان المناسب للبدء ، على ما أعتقد.

sargant هل يعمل اقتراح gabefromutah من أجلك؟

اقتراح ndelangengabefromutah هو نفس المثال الأولي "هذه القصة يعمل" على ما أعتقد؟

في حالة أن هذا ليس خطأ ، فقد يظل تحسينًا مفيدًا لتجنب الاضطرار إلى استخدام المكونات الإضافية لجهات خارجية للحالة.

من المحتمل جدًا إذا بدأنا الأمر بهذه الطريقة ، فقد يعمل.

ndelangen غير متأكد تمامًا من كيفية تفاعل ذلك مع addon-info ، والتي تحتاج إلى معلومات مثل الدعائم الخاصة بالمكون الأساسي الذي تم عرضه.

لقد واجهنا نفس المشكلة ، وهذا اختراق بسيط نقوم به لحلها.

stories.add('this story fails', () => React.createElement(() => {
  const [state, setState] = React.useState(5)
  return (
    <button onClick={() => setState(state + 1)}>
      {state}
    </button>
  )
}))

أوافق على أنه سيكون من الأفضل بكثير أن يتم دعمها محليًا دون اختراق. إذا وافق المشرفون أيضًا ، فربما يمكنني العثور على بعض الوقت للتوصل إلى PR 🙂.

@ kevin940726 سيكون ذلك رائعًا 👍

إضافة ما يلي إلى my .storybook / config.js عملت بالنسبة لي

addDecorator((Story) => <Story />)

لقد طبقت شيئًا مشابهًا ، لكنني أعتقد أن هذا يكسر مجموعة من الإضافات ، على وجه التحديد معلومات إضافية لإخراج وثائق الخاصية. لقد قررت أن استخدام الخطافات أكثر أهمية من تلك المعلومات (لأنني أقوم بإنشاء ذلك بشكل منفصل على أي حال) ولكني أشك في أن ذلك سينطبق على كل القصص القصيرة بشكل عام. لا توجد فكرة عن كيفية التعامل مع خطاف مثل api خارج رد الفعل.

حاولت تنفيذه في الكود المصدري ، لكنني أجد صعوبة في جعله يعمل مع ملحق Storyshot. أعتقد أن هذا سيكون تغييرًا مفاجئًا لأنه سيؤدي إلى إنشاء عقدة أصلية جديدة في كل لقطة. نظرًا لأننا لا نتحكم في العارض الذي يختاره المستخدم ، فلا يمكننا الغوص في مستوى واحد بعمق. أعتقد أنه قد يتعين علينا التفكير في بدائل أخرى ، مثل توثيق الحل وربما توفير بعض واجهة برمجة التطبيقات المساعدة للمستخدمين للاشتراك.

إضافة ما يلي إلى my .storybook / config.js عملت بالنسبة لي

addDecorator((Story) => <Story />)

emjaksa هل يمكنك تقديم مقتطف من هذا من فضلك؟

كان هذا هو الحل البديل لهذه المشكلة:

import React, { useState } from 'react';

import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withInfo } from '@storybook/addon-info';

import SelectField from 'component-folder/SelectField';

/**
 * special wrapper that replaces the `value` and `onChange` properties to make
 * the component work hooks
 */
const SelectFieldWrapper = props => {
  const [selectValue, setValue] = useState('');

  return (
    <SelectField
      {...props}
      value={selectValue}
      onChange={e => {
        setValue(e.target.value);
        action('onChange')(e.target.value);
      }}
    />
  );
};
SelectFieldWrapper.displayName = 'SelectField';

const info = {
  text: SelectField.__docgenInfo.description,
  propTables: [SelectField],
  propTablesExclude: [SelectFieldWrapper]
};

storiesOf('Controls/SelectField', module)
  .addDecorator(withInfo)

  // ... some stories

  // this example uses a wrapper component to handle the `value` and `onChange` props, but it should
  // be interpreted as a <SelectField> component
  .add('change handler', () => 
    <SelectFieldWrapper
      id="employment-status"
      placeholder="some placeholder"
      value={//selectValue}
      onChange={e => {
          // setValue(e.target.value);
      }}
    />, { info });

كما ذكرت لا يزال حلاً ، لكنه يعمل ولا يكسر الملحق info . (لم أختبر الوظائف الإضافية الأخرى)

لم يتم كسر ملحق المعلومات الخاص بي بشرط أن أضفت مصمم القصة أخيرًا.

import React from 'react'

import { configure, addDecorator } from '@storybook/react'
import { withInfo } from '@storybook/addon-info'
import { withKnobs } from '@storybook/addon-knobs'

const req = require.context('../src', true, /\.stories\.js$/)

function loadStories() {
  req.keys().forEach(filename => req(filename))
}

addDecorator(
  withInfo({
    header: false,
  }),
)
addDecorator(withKnobs)
addDecorator((Story) => (
    <Story />
))

configure(loadStories, module)

حل آخر:

لدي مكون أداة يسمى UseState معرف مثل هذا:

export const UseState = ({ render, initialValue }) => {
    const [ variable, setVariable ] = useState(initialValue)
    return render(variable, setVariable)
}

وأنا أستخدمه في قصص مثل هذا:

.add('use state example', () => (
    <UseState
        initialValue={0}
        render={(counter, setCounter) => (            
            <button onClick={() => setCounter(counter + 1)} >Clicked {counter} times</button>
        )}
    />
)

لكني أحب الحل البديل @ kevin940726 الأفضل

أنا غير قادر على إعادة تقديم القصة عند تغيير الحالة. لا تعمل فرض إعادة التقديم أيضًا.

بينما يعمل هذا الرمز جيدًا مع React Hooks

storiesOf("Dropdowns", module).add("Basic", () => <DropdownBasicStory />);

لا يعمل بشكل جيد مع @storybook/addon-info :
Screenshot 2019-05-13 14 35 10

هذا يجعل هذا الحل غير قابل للاستخدام. أيه أفكار؟ Storybook 5.1.0 بيتا.0

artyomtrityak يمكنك تجاوز الخيار propTables في addon-info ؟ سأقوم بحل هذا بشكل صحيح في addon-docs : https://medium.com/storybookjs/storybook-docs-sneak-peak-5be78445094a

shilman هل سيشمل أيضًا مصدر <DropdownBasicStory /> ؟

artyomtrityak سأرى ما يمكنني فعله 😆

مرحباً بالجميع! يبدو أنه لم يكن هناك الكثير مما يحدث في هذه المشكلة مؤخرًا. إذا كانت لا تزال هناك أسئلة أو تعليقات أو أخطاء ، فلا تتردد في مواصلة المناقشة. للأسف ، ليس لدينا الوقت لحل كل مشكلة. نحن دائمًا منفتحون على المساهمات ، لذا يرجى إرسال طلب سحب لنا إذا كنت ترغب في المساعدة. سيتم إغلاق المشكلات غير النشطة بعد 30 يومًا. شكر!

إذا كان أي شخص آخر لا يزال يحصل على هذا ، فقد وجدت أن المشكلة يبدو أنها تضيف أنواع الدعامة إلى مكون وظيفي.

const Dropdown = () => (
  // component content
);

Dropdown.propTypes = {
  ...
}

لسبب ما ، يبدو أن التعليق على .propTypes يجعل الأمر يعمل. لست متأكدًا مما إذا كانت مشكلة تتعلق بتحليل أنواع العناصر للتوثيق أو أي شيء آخر.

لعرض الكود المصدري للمكونات ذات الخطافات

function WithState({ children }) {
  const [value, setValue] = React.useState([]);

  return React.cloneElement(children, {
    value,
    onChange: event => setValue(event.target.value),
  });
}

storiesOf(`${__dirname}`, module).add('Basic', () => (
  <WithState>
    <select value="[parent state]" onChange="[parent func]">
      <option value="Australia">Australia</option>
      <option value="Cambodia">Cambodia</option>
    </select>
  </WithState>
));

مرحباً بالجميع! يبدو أنه لم يكن هناك الكثير مما يحدث في هذه المشكلة مؤخرًا. إذا كانت لا تزال هناك أسئلة أو تعليقات أو أخطاء ، فلا تتردد في مواصلة المناقشة. للأسف ، ليس لدينا الوقت لحل كل مشكلة. نحن دائمًا منفتحون على المساهمات ، لذا يرجى إرسال طلب سحب لنا إذا كنت ترغب في المساعدة. سيتم إغلاق المشكلات غير النشطة بعد 30 يومًا. شكر!

كن حذرًا مع الأسلوب React.createElement و <Story /> أعلاه ، أعتقد أنهما غير صحيحين تمامًا في بعض الحالات ، لأنك تعيد إنشاء مكونات التفاعل (مكون القصة) بدلاً من إرجاع العناصر المعروضة (أثناء استخدام story() في كتاب القصة config.js كما هو موضح في المستندات).

على سبيل المثال ، عندما تحتوي قصتك على Knobs.button الذي يقوم بتشغيل تحديثات الحالة المحلية للمكون ، بعد النقر فوق الزر ، فأنت على الأرجح تقوم بإنشاء مكون قصة جديد بدلاً من تحديث حالة المكون الحالي.

يمكنك التحقق من افتراضاتي باستخدام مقتطف الشفرة البسيط هذا ، حيث لن يتم تحديث القيمة بعد النقر فوق زر المقابض.

storiesOf('Test', module).add('with text', () => {
  return React.createElement(() => {
    const [value, setValue] = React.useState(1);

    Knobs.button('Increase', () => setValue(prev => prev + 1));

    return <span>{value}</span>;
  });
});

لجعلها تعمل ، يمكنك القيام بما يلي:

function MyStory() {
  const [value, setValue] = React.useState(1);

  Knobs.button('Increase', () => setValue(prev => prev + 1));

  return <span>{value}</span>;
}

storiesOf('Test', module).add('with text', () => <MyStory />);

لذلك ، كحل بديل ، قمت بإنشاء غلاف:

import {
  DecoratorParameters,
  Story,
  StoryDecorator,
  storiesOf as origStoriesOf,
} from '@storybook/react';

class ReactStory {
  private readonly story: Story;

  constructor(name: string, module: NodeModule) {
    this.story = origStoriesOf(name, module);
  }

  public add(
    storyName: string,
    Component: React.ComponentType,
    parameters?: DecoratorParameters
  ): this {
    this.story.add(storyName, () => <Component />, parameters);
    return this;
  }

  public addDecorator(decorator: StoryDecorator): this {
    this.story.addDecorator(decorator);
    return this;
  }

  public addParameters(parameters: DecoratorParameters): this {
    this.story.addParameters(parameters);
    return this;
  }
}

new ReactStory('Test', module).add('with text', () => {
  const [value, setValue] = React.useState(1);

  Knobs.button('Increase', () => setValue(prev => prev + 1));

  return <span>{value}</span>;
});

اختياريًا ، يمكنك محاكاة واجهة برمجة تطبيقات Storybook لتقليل أعباء إعادة البناء ، والعودة مرة أخرى لاحقًا عند إصلاح المشكلة.

export function storiesOf(name: string, module: NodeModule) {
  return new ReactStory(name, module);
}

قد أكون مخطئا ، إذا كان الأمر كذلك ، فيرجى إبلاغي بذلك. مقدر جدا!

تا دا !! لقد أصدرت للتو https://github.com/storybookjs/storybook/releases/tag/v5.2.0-beta.10 تحتوي على PR # 7571 الذي يشير إلى هذه المشكلة. قم بالترقية اليوم لتجربتها!

يمكنك العثور على هذا الإصدار التجريبي على علامة @next NPM.

إغلاق هذه القضية. الرجاء إعادة الفتح إذا كنت تعتقد أنه لا يزال هناك المزيد لتفعله.

shilman شكرا !! هل لديك مثال مقتطف الشفرة حول كيفية استخدامه؟

@ shilman شكرا لك!
ولكن لا يزال هناك خطأ:
React Hook يتم استدعاء "useState" في الوظيفة "مكون" وهو ليس مكون دالة React أو دالة React Hook مخصصة

shiranZe هل تستخدم إصدار 5.2 بيتا حديثًا؟

shilman نعم ...

الكود الخاص بي في القصص / المكونات / القائمة / index.js:

مكون const = () => {
const [buttonEl، setButtonEl] = useState (خالية)

const handleClick = (event) => {
    console.log('the event', event)
    setButtonEl(event.currentTarget)
}

return (
    <>
        <IconButton iconName={"menu-hamburger"} size="s" onClick={handleClick} color={"midGray"}></IconButton>

تصدير افتراضي [تمهيدي ، مكون] ؛

وفي القصص / المكونات / index.js:
storiesOf('Components', module) .addDecorator(withKnobs) .add('Text', withReadme(...Menu))

shiranZe أعتقد أنها مشكلة مع addon-readme - ربما تقدم مشكلة هناك؟

شكرا لك @ shilman على ردك. لا أعرف ما إذا كانت هذه هي المشكلة. حاولت بدون addon-readme وما زلت أتلقى نفس الخطأ. هل لديك عنوان URL لكتاب القصة 5.2-بيتا؟
حاولت إلقاء نظرة على https://storybooks-official.netlify.com/ (أخرى | عرض / زر)
لكن لا يمكنني العثور هناك على مثال مع خطافات التفاعل.

ما زلت أواجه مشكلة مع 5.2.0-beta.30 والشيء هو عدم نجاح أي من الحلول البديلة بالنسبة لي ، لأنني أستخدم ملحق المقابض أيضًا.

shiranZe تم إيقاف نشر netlify الخاص بنا (ccndelangen) ولكن يمكنك التحقق من الريبو على الفرع next وتجربته هناك.

sourcesoft أعتقد أن مشكلة "خطافات المعاينة" المتعلقة بالمقابض (ccHypnosphi) لا علاقة لها بهذه المشكلة - الشيء الوحيد المشترك بينهما هو مفهوم الخطافات.

@ shilman شكرا ، أعتقد أنك على حق. بالمناسبة ، اكتشفت كيفية إصلاحها عن طريق التجربة والخطأ ، غيرت الخطاف المخصص:

export const useField = (id, updateField) => {
  const onChange = useCallback((event) => {
    const {
      target: { value },
    } = e;
    updateField(id, value);
  };

  return {
    onChange,
  };
}, []);

إلى

export const useField = (id, updateField) => {
  const onChange = (event) => {
    const {
      target: { value },
    } = e;
    updateField(id, value);
  };

  return {
    onChange,
  };
};

لقد أزلت للتو استخدام useCallback هنا. لست متأكدًا مما إذا كان الإصدار الأول عبارة عن خطاف صالح ولكنه كان يعمل. كما أنه أمر محير بعض الشيء عندما يقول الخطأ Hooks can only be called inside the body of a function component أو وجود إصدار متعدد من React.

في المثال أعلاه ، بعد إزالة useCallback ، هل تستخدم بالفعل تسجيل أي خطاف في useField على الإطلاق؟ 🤔

يبدو أن هناك مشكلة في استخدام الخطافات بالمقابض. إذا كان بإمكان أي شخص تقديم نسخة بسيطة ، فسيسعدني إلقاء نظرة عليها

shilman هل جربت المثال الذي نشرته سابقًا؟ ها هو المقتطف:

storiesOf('Test', module).add('with text', () => {
  return React.createElement(() => {
    const [value, setValue] = React.useState(1);

    Knobs.button('Increase', () => setValue(prev => prev + 1));

    return <span>{value}</span>;
  });
});

إنها تستخدم واجهة برمجة التطبيقات القديمة ، ولكن يجب أن يكون من السهل تحويلها إلى أحدث واجهة برمجة تطبيقات للاختبار. يمكنك العثور على السلوك المتوقع من المنشور الأصلي .

zhenwenc FYI يعمل الكود ، لكنه يقطع استخدام المستندات المقدمة بواسطة react-docgen-typescript-webpack-plugin .

يبدو الحل البديل هشًا بعض الشيء ويتعارض مع المكتبات الأخرى. كبديل ، هل لدى شخص ما خبرة في استخدام ؟: https://github.com/Sambego/storybook-state

بالنسبة لأولئك الذين يبحثون عن رسالة الخطأ عبر Google:

تلقيت هذا الخطأ عند تغيير مكون فئة إلى مكون وظيفي باستخدام خطافات و useState كان يستورد بشكل غير صحيح من @storybook/addons . كنت أحتاجه ليأتي من react بدلاً من @storybook/addons ... فشل الاستيراد التلقائي.

مجرد الرد على طلب orpheus للحصول على قصاصة

إضافة ما يلي إلى my .storybook / config.js عملت بالنسبة لي
addDecorator((Story) => <Story />)

emjaksa هل يمكنك تقديم مقتطف من هذا من فضلك؟

diff --git a/.storybook/config.js b/.storybook/config.js
--- a/.storybook/config.js
+++ b/.storybook/config.js
@@ -1,6 +1,9 @@
-import { configure } from '@storybook/react';
+import { configure, addDecorator } from '@storybook/react';
+import React from 'react';

 // automatically import all files ending in *.stories.js
 configure(require.context('../stories', true, /\.stories\.js$/), module);
+
+addDecorator((Story) => <Story />);

النتيجة (أكمل .storybook/config.js ):

import { configure, addDecorator } from '@storybook/react';
import React from 'react';

// automatically import all files ending in *.stories.js
configure(require.context('../stories', true, /\.stories\.js$/), module);

addDecorator((Story) => <Story />);

لست متأكدًا مما إذا كانت هذه هي أفضل طريقة للحصول على ردة فعل تعمل داخل القصص المصورة ، ولكن تغليف القصة القصيرة في مكونها الخاص <Story /> المكون يعمل هنا مع "@storybook/react": "^5.2.6", .

قبل القيام بذلك ، كلما قمت بتحديث مقبض (على سبيل المثال: منطقي) ، كان يعمل على التصيير الأول ، ولكنه توقف بعد ذلك عن العرض. فوق حل حل ذلك. راجع للشغل ، لست متأكدًا من أنها ممارسة جيدة لاستخدام خطافات التفاعل في القصص المصورة ، فقط اسخر من كل شيء إذا كان ذلك ممكنًا ، فمن الأفضل على الأرجح بهذه الطريقة.

وصف الخطأ

لا يمكن استخدام الخطافات مباشرة في القصة ، فشل مع Hooks can only be called inside the body of a function component .

لإعادة إنتاج

رمز المثال:

import React from 'react'

import { storiesOf } from '@storybook/react'

const stories = storiesOf('Hooks test', module)

const TestComponent: React.FC = () => {
  const [state, setState] = React.useState(5)
  return (
    <button onClick={() => setState(state + 1)}>
      {state}
    </button>
  )
}

stories.add('this story works', () => <TestComponent />)

stories.add('this story fails', () => {
  const [state, setState] = React.useState(5)
  return (
    <button onClick={() => setState(state + 1)}>
      {state}
    </button>
  )
})

سلوك متوقع
القصة الأولى تعمل بشكل جيد ، القصة الثانية تفشل في التصيير الأولي

إصدارات
@storybook/[email protected]
[email protected]
[email protected]

=======================================

لا تستخدم وظيفة السهم لإنشاء مكونات وظيفية.
افعل كواحد من الأمثلة أدناه:

function MyComponent(props) {
  const [states, setStates] = React.useState({ value: '' });

  return (
    <input
      type="text"
      value={states.value}
      onChange={(event) => setStates({ value: event.target.value })}
    />
  );
}

أو

//IMPORTANT: Repeat the function name

const MyComponent = function MyComponent(props) { 
  const [states, setStates] = React.useState({ value: '' });

  return (
    <input
      type="text"
      value={states.value}
      onChange={(event) => setStates({ value: event.target.value })}
    />
  );
};

إذا كانت لديك مشاكل مع "ref" (ربما في حلقات) ، فإن الحل هو استخدام forwardRef ():

// IMPORTANT: Repeat the function name
// Add the "ref" argument to the function, in case you need to use it.

const MyComponent = React.forwardRef( function MyComponent(props, ref) {
  const [states, setStates] = React.useState({ value: '' });

  return (
    <input
      type="text"
      value={states.value}
      onChange={(event) => setStates({ value: event.target.value })}
    />
  );
});

كيف يمكن تحقيق ذلك في MDX؟

ولكن لا يزال هناك خطأ:
React Hook يتم استدعاء "useState" في الوظيفة "مكون" وهو ليس مكون دالة React أو دالة React Hook مخصصة
https://github.com/storybookjs/storybook/issues/5721#issuecomment -518225880

كنت أواجه نفس المشكلة بالضبط. الإصلاح هو تكبير تصدير القصة المحددة.

 استيراد رد فعل من رد فعل ؛
 استيراد Foo من "./Foo" ؛

 تصدير الافتراضي {
 العنوان: "Foo"؛
 } ؛

 تصدير const Basic = () => <Foo />

تقول المستندات إن الكتابة بالأحرف الكبيرة موصى بها ولكنها ضرورية إذا كنت تريد أن يختفي هذا التحذير.

في حالتي ، كانت المشكلة أنني نسيت استيراد الخطاف الذي كنت أستخدمه.

إضافة ما يلي إلى my .storybook / config.js عملت بالنسبة لي

addDecorator((Story) => <Story />)

تضمين التغريدة تم اختباره ويعمل بشكل جيد على Storybook v5.3.

واجهت نفس المشكلة ، مكون رد الفعل الوظيفي الخاص بي به useState(value) و value لم يعيد عرض القيمة الجديدة من Knobs ، هذه المشكلة ناتجة عن useState:

من مستندات React:
Screen Shot 2020-08-07 at 19 00 04

حل العمل Storybook v5.3:

تحديث Preview.js

.storybook/preview.js
import React from 'react'; // Important to render the story
import { withKnobs } from '@storybook/addon-knobs';
import { addDecorator } from '@storybook/react';

addDecorator(withKnobs);
addDecorator(Story => <Story />); // This guy will re-render the story

وكذلك تحديث main.js

.storybook/main.js
module.exports = {
  stories: ['../src/**/*.stories.jsx'],
  addons: [
    '@storybook/preset-create-react-app',
    '@storybook/addon-knobs/register', // Attention to this guy
    '@storybook/addon-actions',
    '@storybook/addon-links',
  ],
  webpackFinal: async config => {
    return config;
  },
};



هل يعرف أحد لماذا هذا التزيين يجعل الخطافات تعمل؟

"" tsx
SomeComponent.decorators = [(قصة) => ]

tmikeschu لأن <Story /> يلف الكود في React.createElement وهو أمر ضروري للخطافات.

@ shilman شكرا لك!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات