Giter VIP home page Giter VIP logo

addon-redux's People

Contributors

coderkevin avatar dependabot[bot] avatar frodare avatar samatcd avatar sebastiengllmt avatar type1j avatar zeriley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

addon-redux's Issues

"redux state" panels action send to FIRST store.

If i want to display multiple stories with addon-docs, i need to create multiple stores.
BUT "redux state" panel action send to FIRST store.
So, i cannot use "redux state" panel.

withRedux.ts

  if (!initialized) {
    channel.on(events.SET_STATE, state => store.dispatch(setStateAction(state)))
    channel.on(events.DISPATCH, action => store.dispatch(action))
  }

  initialized = true

Store only works on initial load

I am trying to setup addon but store will be correct on first story but as soon as I switch story I get an empty object as store and have to refresh. Changing values on first page works so the store is hooked up correctly but I guess something about the decorator is not.

I am not using same import system:


module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/preset-create-react-app",
    "@chakra-ui/storybook-addon",
    "addon-redux",
  ],
  framework: "@storybook/react",
  core: {
    builder: "webpack5",
  },
};

preview.js


import { Provider } from "react-redux";
import { addDecorator } from "@storybook/react";
import { store } from "../src/app/store";

export const decorators = [
  (storyFn) => <Provider store={store}>{storyFn()}</Provider>,
];


And the store.ts file (redux toolkit)

import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit";
// import counterReducer from '../features/counter/counterSlice';

import { enhancer } from "addon-redux";

import gameBoardReducer from "../features/GamePage/gameBoardSlice";
export const store = configureStore({
reducer: {
gameBoard: gameBoardReducer,
},
enhancers: [enhancer],
});


export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  RootState,
  unknown,
  Action<string>
>;

I can even change the store using webextension and that change is visible on all pages (so not cleared) when changing story pages. However the addon bar will just stay "select node" after the first page.

Edit: I don't know if it is a refresh problem of sorts. I tried adding "arg" to a story. Changing the story from that and the"Redux store" tab will refresh and work again (but will reset to empty object if switching story again).
Maybe a redux toolkit problem and manipulating the state outside of the slices? Anyone got react toolkit to work correctly with this?
From the redux developer toolkit the state seem to be correct but still.

Example usage with @reduxjs/toolkit

Redux Toolkit exposes its own utility function for creating stores called configureStore. When using this function, you need to pass all enhancers in as an array.

The type that Redux Tookit expects is StoreEnhancer[] | (StoreEnhancer[] => StoreEnhancer[])

This worked well with the v1 version of addon-redux. However, the type of withReduxEnhancer in v2 now uses

(createStore: StoreCreator) => (reducer: Reducer, state: State, enhancer: StoreEnhancer) 

which isn't compatible with Redux Toolkit.

Would be great to see an example of how to setup this library with Redux Toolkit given how prevalent that library is.

Invalid PropType Check in StateChange

warning.js:33 Warning: Failed prop type: Invalid prop date of type string supplied to StateChange, expected object.
in StateChange (created by HistoryPanel)
in HistoryPanel (created by lifecycle(HistoryPanel))
in lifecycle(HistoryPanel) (created by withHandlers(lifecycle(HistoryPanel)))
in withHandlers(lifecycle(HistoryPanel)) (created by withState(withHandlers(lifecycle(HistoryPanel))))
in withState(withHandlers(lifecycle(HistoryPanel))) (created by withState(withState(withHandlers(lifecycle(HistoryPanel)))))
in withState(withState(withHandlers(lifecycle(HistoryPanel)))) (created by withState(withState(withState(withHandlers(lifecycle(HistoryPanel))))))
in withState(withState(withState(withHandlers(lifecycle(HistoryPanel))))) (created by withState(withState(withState(withState(withHandlers(lifecycle(HistoryPanel)))))))
in withState(withState(withState(withState(withHandlers(lifecycle(HistoryPanel)))))) (created by AddonPanel)
in div (created by AddonPanel)
in div (created by AddonPanel)
in div (created by AddonPanel)
in AddonPanel (created by Container(AddonPanel))
in Container(AddonPanel) (created by Layout)
in div (created by Layout)
in div (created by Pane)
in Pane (created by SplitPane)
in div (created by SplitPane)
in SplitPane (created by Layout)
in div (created by Pane)
in Pane (created by SplitPane)
in div (created by SplitPane)
in SplitPane (created by Layout)
in div (created by Layout)
in Layout (created by Container(Layout))
in Container(Layout)
in div

Stories all share same store

I created a custom decorator as recommended... but the decorators are all invoked on Storybook load, therefore the story that occurs last overwrites the store for previous stories.

Is there a way to ensure each story has its own state in the Redux store? I don't see a way to do that at the moment, as the addon store appears to be a single instance, and Storybook does not reinitialize Redux on story change.

Thanks in advance.

Support storybook v5

I 've upgraded recently to v5 and started having some weird warnings and errors in console. I 've dropped addon-redux and errors went away so probably some things need to be changed in order to support this. Do you have a clue what these might be? I could provide a helping hand if needed ๐Ÿ˜ƒ

PARAM_REDUX_MERGE_STATE for Storybook args

Background

Right now we have two ways of injecting data into Redux

  1. Use a parameter PARAM_REDUX_MERGE_STATE (can only be static data)
  2. Use an arg ARG_REDUX_PATH (inject the value of a control to a specific path)

Problem

Using ARG_REDUX_PATH works well when your Storybook control maps directly to a value in your Redux store, but it doesn't allow any way to do dependent state

ex: imagine you have a single control that needs to modify multiple parts of your Redux store.

Solution

One simple solution would be to allow ARG_REDUX_PATH to be a function that takes the current value of the control as its argument and then returns a subset of the Redux state to override (similar to PARAM_REDUX_MERGE_STATE)

theme: {
    control: { type: 'boolean' },
    [ARG_REDUX_PATH]: isMobile => ({ isMobile, supportsBluetooth: isMobile })
  },

However I feel this isn't a great solution because it just pushes the problem down one layer -- what happens if you need to set Redux state based off the combination of multiple Storybook controls?

You could solve this by making that the lambda takes a more complicated argument like

Main.argTypes = {
    allowedBluetoothPermission: {
        control: { type: 'boolean' },
     },
    theme: {
        control: { type: 'boolean' },
        [ARG_REDUX_PATH]: (isMobile, args) => ({ isMobile, supportsBluetooth: isMobile && args.allowedBluetoothPermission })
      },
}

Store state persists between stories

I think #14 is the same issue, but I think this was closed even though the issue wasn't fixed.

Problem

All stories share a single redux store. That means that if you change the Redux store on one story (say, you use ARG_REDUX_PATH or PARAM_REDUX_MERGE_STATE), the state of the store isn't reset by going to a different story.

Solution

Probably the solution is to make switching stories dispatch a RESET action that sets the state to undefined at the root level (setting state to undefined makes Redux reset to the initial state).

In fact, there already exists a very short library that does exactly this (https://github.com/wwayne/redux-reset) but they have some extra complexity to it

Crash when rendering Row in HistoryView

Version: 2.0.5

When I interact with the story in any way (even just clicking on empty space) triggers the following error. I don't have any non-serializable types in my Redux state, so not sure what could be causing this.

The error seems to come from the HistoryView calling JSON.parse(diff) when diff is undefined. Probably there needs to be code added to handle an undefined diff (or maybe this is never suppose to happen?)

VM749965:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at Row (vendors~main.manager.bundle.js:28869)
    at renderWithHooks (vendors~main.manager.bundle.js:91442)
    at mountIndeterminateComponent (vendors~main.manager.bundle.js:94121)
    at beginWork (vendors~main.manager.bundle.js:95235)
    at HTMLUnknownElement.callCallback (vendors~main.manager.bundle.js:76827)
    at Object.invokeGuardedCallbackDev (vendors~main.manager.bundle.js:76876)
    at invokeGuardedCallback (vendors~main.manager.bundle.js:76931)
    at beginWork$1 (vendors~main.manager.bundle.js:99842)
    at performUnitOfWork (vendors~main.manager.bundle.js:98796)


vendors~main.manager.bundle.js:96166 The above error occurred in the <Row> component:
    in Row (created by HistoryView)
    in tbody (created by HistoryView)
    in table (created by Context.Consumer)
    in Styled(table) (created by HistoryView)
    in HistoryView
    in div (created by AddonPanel)
    in AddonPanel
    in div (created by Context.Consumer)
    in Styled(div)
    in div (created by Context.Consumer)
    in Styled(div)
    in Unknown
    in Unknown
    in Unknown
    in Unknown (created by ManagerConsumer)
    in ManagerConsumer (created by Panel)
    in Panel (created by Layout)
    in div (created by Context.Consumer)
    in Styled(div) (created by Panel)
    in Panel (created by Layout)
    in div (created by Context.Consumer)
    in Styled(div) (created by Main)
    in div (created by Context.Consumer)
    in Styled(div) (created by Main)
    in Main (created by Layout)
    in Layout (created by Context.Consumer)
    in WithTheme(Layout)
    in Unknown
    in div (created by Context.Consumer)
    in Styled(div)
    in Unknown
    in Unknown (created by SizeMeRenderer(Component))
    in SizeMeReferenceWrapper (created by SizeMeRenderer(Component))
    in SizeMeRenderer(Component) (created by SizeMe(Component))
    in SizeMe(Component)
    in ThemeProvider
    in Unknown (created by ManagerConsumer)
    in ManagerConsumer (created by Manager)
    in EffectOnMount (created by Manager)
    in Manager (created by Context.Consumer)
    in Location (created by QueryLocation)
    in QueryLocation (created by Root)
    in LocationProvider (created by Root)
    in HelmetProvider (created by Root)
    in Root

React will try to recreate this component tree from scratch using the error boundary you provided, LocationProvider

vendors~main.manager.bundle.js:15740  manager  received storybook/addon-redux/on_dispatch but was unable to determine the source of the event

Support for newer version of redux / react-redux

This addon works correctly on versions:

    "react-redux": "^5.1.1",
    "redux": "^3.5.2",

But, on versions:

    "react-redux": "^6.0.0",
    "redux": "^4.0.1",

I receive error:
Invariant Violation: Could not find "store" in the context of "Connect(Container)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(Container) in connect options.

Npm 2.0.11 is not 2.0.11 tag

So I noticed that the version you get downloading 2.0.11 from npm does not seem to be matching that tag here.

It can be seen by
#32
should be included in it but it is not. Or I am missing something.

Storybook 7 and React 18 support

Firstly thank you for putting together this storybook addon.
I've recently upgraded to Storybook 7 and React 18.

The package.json of this package specify the following peer deps

"@storybook/addons": "^6.2.9",
"@storybook/api": "^6.2.9",
"@storybook/components": "^6.2.9",
"@storybook/core-events": "^6.2.9",
"@storybook/theming": "^6.2.9",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0",

NPM generates warnings when trying to install because of the above.

Could this package be upgraded to support React 18 and Storybook 7 please.

Incorrect Key use in ViewMode

warning.js:33 Warning: Each child in an array or iterator should have a unique "key" prop.

Check the render method of ViewMode. See https://fb.me/react-warning-keys for more information.
in button (created by ViewMode)
in ViewMode (created by StatePanel)
in div (created by StatePanel)
in StatePanel (created by lifecycle(StatePanel))
in lifecycle(StatePanel) (created by withHandlers(lifecycle(StatePanel)))
in withHandlers(lifecycle(StatePanel)) (created by withState(withHandlers(lifecycle(StatePanel))))
in withState(withHandlers(lifecycle(StatePanel))) (created by withState(withState(withHandlers(lifecycle(StatePanel)))))
in withState(withState(withHandlers(lifecycle(StatePanel)))) (created by withState(withState(withState(withHandlers(lifecycle(StatePanel))))))
in withState(withState(withState(withHandlers(lifecycle(StatePanel))))) (created by withState(withState(withState(withState(withHandlers(lifecycle(StatePanel)))))))
in withState(withState(withState(withState(withHandlers(lifecycle(StatePanel)))))) (created by AddonPanel)
in div (created by AddonPanel)
in div (created by AddonPanel)
in div (created by AddonPanel)
in AddonPanel (created by Container(AddonPanel))
in Container(AddonPanel) (created by Layout)
in div (created by Layout)
in div (created by Pane)
in Pane (created by SplitPane)
in div (created by SplitPane)
in SplitPane (created by Layout)
in div (created by Pane)
in Pane (created by SplitPane)
in div (created by SplitPane)
in SplitPane (created by Layout)
in div (created by Layout)
in Layout (created by Container(Layout))
in Container(Layout)
in div

Seem to be getting a different state not mine?

Hi,

I am in need of some help, I've been trying to figure this out for months but can't seem to find any answer or clue to what is going on.

When I am adding the decorator this is the state I am seeing. I can't figure out why this is happening.
I am seeing this in version 1.0.0 and 1.1.0.
image
my state appears to be withing the computedStates array.
image

The setup
.storybook/addons.js
image
.storybook/preview.js
image
image

store
image
image

package.json scripts
image

example storybook
image
image

Could anyone please advise and save my sanity?

StatePanel - Warning: Each child in a list should have a unique "key" prop.

Hello, everyone. It's great to have an addon for redux in storybooks. I tried to used it to develop some components, still I have following warning in chrome dev instruments console after installing addon-redux (v1.0.0):

image

I also run the latest stable storybook:

    "@storybook/addon-actions": "^5.1.3",
    "@storybook/addon-links": "^5.1.3",
    "@storybook/cli": "5.1.3",
    "@storybook/react": "5.1.3",
    "storybook": "1.0.0",
    "react": "^16.5.2"

I will play around of this problem and let you know if something may fix it.

feature request: allow JS objects in PARAM_REDUX_MERGE_STATE

Currently PARAM_REDUX_MERGE_STATE needs to be a string object (will crash trying to JSON.parse an object if you pass an object in instead)

Given that in Redux, best practice is to only ever use serializable data I feel like a JS object should be allowed as a value here instead of a string. Internally, you could use the typeof of the variable to decide to call JSON.stingify on the object is used instead if you need that for some reason

Allow setting default state based off args

Background

This library provides a way to override the default Redux state by setting the PARAM_REDUX_MERGE_STATE parameter for the story.
This works for basic usage, but it means nothing in your Redux state can leverage controls (the recommended way to provide knobs in Storybook as of Storybook v6)

Motivation

An example of why this would be useful is I would like all my stories to have a control for the language used, so it has to be part of the component "args". However, "selectedLanguage" is also part of my Redux state so I would like to inject the arg value using this addon.

Solution

I asked the Storybook team and they said this is not solvable using parameters as they are meant to be static. This is the solution they proposed:

i think a lot of the issue is that many addons were written before args/globals existed, and we haven't been prescriptive enough to get addon authors to use them as intended.

parameters are great for configuring things but if you want to support dynamic data, you need to use args/globals and many addons use parameters because that was the only configuration mechanism until 6.0 and all of the existing addons use them

Globals doesn't sound like the right solution since this is a per-story config, so probably args need to be used instead.

There seems to be a related discussion here.

Middleware gets ignored when dispatching from React

Problem statement

Supposed you have the following custom middle ware that simply logs any action that happens

const customMiddleWare = store => {
  console.log('store');
  return next => {
    console.log('next');
    return action => {
      console.log(`Middleware ran ${JSON.stringify(action)}`);
      next(action);
    }
  }
};

const createMiddlewareEnhancer = () => {
  const middleware = []
  middleware.push(customMiddleWare);
  return applyMiddleware(...middleware)
}

If you call

store.dispatch({
  type: 'asdf'
})

It will properly get logged in the custom middleware.

However, if you dispatch an action from a React component while running Storybook with addon-redux,
It will instead print next but never print the action.

Why this is problematic

If you're using redux-thunk, your React UI made be triggering actions where the action is a function instead of an object.
Since addon-redux ignores middlewares, the redux-thunk middleware gets ignore and then an error is thrown that Redux found an action that is a function.

Missing dispatch return values

See: addon-redux/src/redux/enhancer.ts

    const enhanceDispatch: Enhancer<Dispatcher> = dispatch => action => {
    const prev = store.getState()
    dispatch(action)
    const next = store.getState()
    if (listener !== null) listener(action, prev, next)
  }

This will break for scenarios where the value of the dispatch is read.
In my case when working with redux toolkit - query mutations.

Adding a return statement like below fixed it for me.

    const enhanceDispatch: Enhancer<Dispatcher> = dispatch => action => {
    const prev = store.getState()
    const result = dispatch(action)
    const next = store.getState()
    if (listener !== null) listener(action, prev, next)
    return result;
  }

Regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.