addon-jsx icon indicating copy to clipboard operation
addon-jsx copied to clipboard

How to display classes with state

Open batjko opened this issue 8 years ago • 10 comments

We have a component that only makes sense if it is used as a class, because we need to demonstrate how it handles state.

I can't find a way of letting the JSX output of my story show the entire class. If I return the class in .addWithJsx, the component simply won't show up at all.

Any ideas?

batjko avatar Sep 21 '17 12:09 batjko

Hi, I don't really understand what you mean :/

Can you provide an example of what your component look like and what you want as a result in the addon panel ?

wcastand avatar Sep 21 '17 18:09 wcastand

So here's an example. Essentially, in order to show how the component in question can be controlled by a surrounding container (a class with state and some methods), I'd like to show this whole class in the JSX tab of storybook:

.addWithJSX('Controlled table (w/ external state)',
    withNotes('Using React state to control the table ')(() => {

      class TableContainer extends React.Component {
        constructor() {
          super()
          this.state = {
            rows: [],
            loading: true,
          }
        }

        fetchData = (query) => {
          this.setState({ loading: true })

          fetchServer(query).then((res) => {
            this.setState({
              rows: res.data,
              pages: res.pages,
              loading: false,
            })
          })
        }

        render() {
          const { rows, columns, loading } = this.state

          return (
            <AwesomeTable
              onChange={this.fetchData}
              loading={loading}
              data={rows}
              columns={columns}
            />
          )
        }
      }

      return <TableContainer />
    }),
  )

But all that comes up there is <TableContainer />. Is it possible to print this whole thing?

batjko avatar Sep 22 '17 07:09 batjko

Hi, sorry for the delay, i was on vacation. I'm sorry but right now, i think we can't do that, mainly because the addon only receive the return statement and reverse it to the JSX. It doesn't have access to the source code of the story function.

wcastand avatar Oct 02 '17 08:10 wcastand

It would be fine if I could just add a return in front of my class declaration (which would give you the whole JSX of the return), but that results in nothing coming up at all, breaking the story somehow.

Perhaps that would be doable at some point?

batjko avatar Oct 02 '17 08:10 batjko

I tried that too but storybook doesn't accept the class as a return statement because it can't render it. So i guess we should see with storybook if that possible to send the class and render it, but even then i'm not sure this addon can show the whole logic.

The jsx you see in the panel is an interpretation of the rendered story and the story rendered won't contain the logic, only the react elements :/

storybook return me this error :

capture d ecran 2017-10-02 a 10 33 50

wcastand avatar Oct 02 '17 08:10 wcastand

Yea, shame. A future version of storybook will probably fix that. No worries, thanks for checking though.

batjko avatar Oct 02 '17 08:10 batjko

Something we can do on the storybook side?

ndelangen avatar Oct 25 '17 15:10 ndelangen

A way to help would be to accept a React class as a the return statement, but even then i'm not sure storybook-addon-jsx can handle this kind of code because we only able to reverse to JSX and js code source.

A more general way would be to give access to the untranspiled code (source code) in the object send to the addon.

wcastand avatar Oct 25 '17 16:10 wcastand

hi, i know this is a bit old, but it's also the top result on quick google searches relating to this issue, so i thought i'd add a comment

you can just define your class elsewhere in the file like you normally would. rather than doing something like you suggested

// your example
 withNotes('Using React state to control the table ')(() => {
      class TableContainer extends React.Component {

you can instead have it defined outside of the 'storiesOf' chain altogether (but in the same file), and then render it like you normally would

 withNotes('Using React state to control the table ')(() => {
    return <TableContainer />;
})

at least, in @batjko 's example, nothing is being "passed in" from above, so it's not strictly coupled to the storybook functions at all.

ghost avatar Sep 04 '18 07:09 ghost

I just encountered a similar issue: Some of our components are using a theme from context which requires us to use either a <Theme>{render...}</Theme> render-props component or a useTheme hook which also creates a new component.

All we see in the addon is a simple <Theme /> or sth. which makes sense to how the plugin works, but literally kills any benefit for us. I tried to use onBeforeRender and just return a hard-coded JSX string which I thought is what onBeforeRender can do, but somehow it does not work. Am I doing sth. wrong here? If not, how about having a config option to provide a custom JSX string? That way our users would get the most of it in all places.

robinweser avatar May 07 '19 07:05 robinweser