最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - I want storybook addon actions to display its standard "log" message AND the actual component eve

programmeradmin7浏览0评论

I can't seem to figure out how to get my event handling function to do its logic to update the UI AND storybook's addon - actions() to log the output.

The reason I want the UI to update is because we're using cypress.io for testing. We've hacked/stubbed the actions messaging (pretty cool, window.postMessage) to access the action message which allows the use of action("functionName"), instead of wiring up a event handling function in [file].stories.tsx. I'd like to do both for my sanity. To check the action message, its a few clicks. I'd rather just see the item get removed. With that, for testing, I'd like to expect the action message (I'm able to do that). We are using alert() to check if something fired, and I'm not a fan.

If this just seems unnecessary, or counter intuitive/productive, do elaborate.

If it helps... <List /> is just that, but has an action button on each item to remove the item from the list.

Using onRemove={actionHandler} prop, below, in List does just that in the UI, removes the item and Cypress is happy, but need the alert() to track. But cant wire up the action() anywhere and no log in the GUI.

If I REMOVE onRemove={actionHandler} and unment // onRemove: action("removeItem"), I get the action log I want, but the Item doesn't remove.

I understand actions are supposed to mimic event handler's, but I'd like it to do that AND fire the actual event... if possible or reasonable.

List.stories.tsx
// storybook addons
import { withKnobs } from "@storybook/addon-knobs";

// deps
import React from "react";
import { action } from "@storybook/addon-actions";

// utils
import { CustomEvent } from "../../hooks";

// ponents
import { Item } from "./Item"
import { List } from "./ListItems"
import { InputHeader } from "../inputs/InputHeader";

// create test states for target dropdown
export default {
  ponent: List,
  title: "Lists|With Action",
  decorators: [withKnobs]
};

const listItemsData = {
    values: ['Test Value 1', 'Test Value 2', 'Test Value 3', 'Test Value 4', 'Test Value 5'],
    name: "test list story",
    // onRemove: action("removeItem")
};

export const listWithActionButton = () => {
    const [listItemState, setListItemState] = React.useState(listItemsData)
    const actionHandler = (event: CustomEvent<string[]>) => {
        // action("removeItem")()
        setListItemState(prevState => ({
            ...listItemState,
            values: event.target.value,
        }))
    };

    return (
        <>
        <InputHeader headerText="List with Action Buttons" />
        <br/>
        <List 
            {...listItemState}
            onRemove={actionHandler}
            />
        </>
    )
};

List.tsx
export const List = ({name, values, onRemove}) => {
  const removeItem = (index: number) => {
      // this is what I want to fire AS WELL as the action log.
      const top = values.slice(0, index);
      const bottom = values.slice(index + 1);
      const updatedOptions = [...top, ...bottom]

      // Fire a custom event to match what our useForm hook expects
      const event: CustomEvent<string[]> = {
        target: {
          value: updatedOptions,
          name
        },
      };
      return onRemove(event);
    };

    return (
        <ListStyle>
            {
                values.map((item, index) => {
                    return (
                        <Item 
                            key={index} 
                            value={item} 
                            removeItem={removeItem}
                            itemIndex={index}
                        />)
                })
            }
        </ListStyle>
    )
};

I can't seem to figure out how to get my event handling function to do its logic to update the UI AND storybook's addon - actions() to log the output.

The reason I want the UI to update is because we're using cypress.io for testing. We've hacked/stubbed the actions messaging (pretty cool, window.postMessage) to access the action message which allows the use of action("functionName"), instead of wiring up a event handling function in [file].stories.tsx. I'd like to do both for my sanity. To check the action message, its a few clicks. I'd rather just see the item get removed. With that, for testing, I'd like to expect the action message (I'm able to do that). We are using alert() to check if something fired, and I'm not a fan.

If this just seems unnecessary, or counter intuitive/productive, do elaborate.

If it helps... <List /> is just that, but has an action button on each item to remove the item from the list.

Using onRemove={actionHandler} prop, below, in List does just that in the UI, removes the item and Cypress is happy, but need the alert() to track. But cant wire up the action() anywhere and no log in the GUI.

If I REMOVE onRemove={actionHandler} and unment // onRemove: action("removeItem"), I get the action log I want, but the Item doesn't remove.

I understand actions are supposed to mimic event handler's, but I'd like it to do that AND fire the actual event... if possible or reasonable.

List.stories.tsx
// storybook addons
import { withKnobs } from "@storybook/addon-knobs";

// deps
import React from "react";
import { action } from "@storybook/addon-actions";

// utils
import { CustomEvent } from "../../hooks";

// ponents
import { Item } from "./Item"
import { List } from "./ListItems"
import { InputHeader } from "../inputs/InputHeader";

// create test states for target dropdown
export default {
  ponent: List,
  title: "Lists|With Action",
  decorators: [withKnobs]
};

const listItemsData = {
    values: ['Test Value 1', 'Test Value 2', 'Test Value 3', 'Test Value 4', 'Test Value 5'],
    name: "test list story",
    // onRemove: action("removeItem")
};

export const listWithActionButton = () => {
    const [listItemState, setListItemState] = React.useState(listItemsData)
    const actionHandler = (event: CustomEvent<string[]>) => {
        // action("removeItem")()
        setListItemState(prevState => ({
            ...listItemState,
            values: event.target.value,
        }))
    };

    return (
        <>
        <InputHeader headerText="List with Action Buttons" />
        <br/>
        <List 
            {...listItemState}
            onRemove={actionHandler}
            />
        </>
    )
};

List.tsx
export const List = ({name, values, onRemove}) => {
  const removeItem = (index: number) => {
      // this is what I want to fire AS WELL as the action log.
      const top = values.slice(0, index);
      const bottom = values.slice(index + 1);
      const updatedOptions = [...top, ...bottom]

      // Fire a custom event to match what our useForm hook expects
      const event: CustomEvent<string[]> = {
        target: {
          value: updatedOptions,
          name
        },
      };
      return onRemove(event);
    };

    return (
        <ListStyle>
            {
                values.map((item, index) => {
                    return (
                        <Item 
                            key={index} 
                            value={item} 
                            removeItem={removeItem}
                            itemIndex={index}
                        />)
                })
            }
        </ListStyle>
    )
};
Share Improve this question edited Jan 10, 2020 at 11:57 ouflak 2,52310 gold badges45 silver badges52 bronze badges asked Jan 9, 2020 at 17:10 AJdevsAJdevs 411 silver badge7 bronze badges 1
  • onRemove={(...args) => { action('log'); actionHandler(...args); }} ? – Emile Bergeron Commented Jan 9, 2020 at 17:15
Add a ment  | 

1 Answer 1

Reset to default 6

You can do something like this if you want to fire an action AND execute your function.

  <Button
    onClick={(e) => {
      action('click')(e);
      removeItem();
    }}
    selected={state}
  >

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论