Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decorated component re-mounts on dispatch #27

Open
kovcic opened this issue Feb 11, 2022 · 2 comments
Open

Decorated component re-mounts on dispatch #27

kovcic opened this issue Feb 11, 2022 · 2 comments

Comments

@kovcic
Copy link

kovcic commented Feb 11, 2022

Hello,

I'm trying to use the context addon for input-based components.
For example:

import { useEffect } from 'react';
import { withReactContext } from 'storybook-react-context';

const InputWrapper = ({ value, children }) => (
  <div>
    <p>{value}</p>
    {children}
  </div>
);

export default {
  component: InputWrapper,
  title: 'InputWrapper',
};

export const Input = (args, { context: [ state, dispatch ] }) => {
  const handleChange = (e) => {
    const { target: { value } } = e;

    dispatch({ value });
  };

  useEffect(() => {
    console.info('mount');

    return () => {
      console.info('unmount');
    }
  }, [])

  return (
    <InputWrapper value={state.value}>
      <input type="text" value={state.value} onChange={handleChange} />
    </InputWrapper>
  );
};
Input.decorators = [withReactContext({
  initialState: {
    value: 'Hello',
  },
})];
Input.args = {};

I'm noticing that on every dispatch (input value change) story is re-mounted.
Is there a way to avoid that, because on each keystroke input is re-mounted and focus is lost?

Thx

@LongLiveCHIEF
Copy link

LongLiveCHIEF commented Feb 11, 2022

This is a fundamental laws of react thing. Context is essentially a prop that you don't have to pass. That means it is subject to the same rules as props... and when you change a component's props, the component re-renders.

@acha5066
Copy link

acha5066 commented Sep 26, 2023

I think this is actually a bug. I was able to get the focus to stay on the input by swapping out this decorator with my own simple one. The below decorator is working for me:

const withMyContext = (args) => (Story) => {
  const [state, dispatch] = useReducer(filterReducer, args.initialState);
  return (
    <SearchContext.Provider value={[state, dispatch]}>
      {Story()}
    </SearchContext.Provider>
  );
};
decorators: [
    withMyContext({
      Context: SearchContext,
      initialState: {
        ...initialPredictiveState,
        settings: {
          search: {
            suggestions: {
              title: "Recommended search text",
            },
          },
        },
      },
    }),
  ],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants