Controlled Input Loses Focus in Docs when Using useArgs Hook
See original GitHub issueDescribe the bug
Using useArgs hook to update a controlled text input React component works fine on the “Canvas” tab, but when using it in Docs mode, we encounter an issue where the input loses focus after every key press (hence, every time the args are updated). This makes interacting with it in Docs mode extremely difficult.
To Reproduce Steps to reproduce the behavior:
- Go to Docs tab
- Click on the story for
TextFieldcomponent - Attempt to type multiple characters into the input
- See error
Expected behavior The component should update the same within Docs as it does within the standard Canvas tab. The input should not lose focus when args are updated.
Screenshots If applicable, add screenshots to help explain your problem.
Code snippets Component:
import React from 'react';
import PropTypes from 'prop-types';
/**
* Wrapper around a text input
*/
export const TextField = ({ label = 'Foo', value = '', onChange }) => {
const handleChange = (event) => onChange?.(event.target.value);
return (
<React.Fragment>
<label>{label}</label>
<input type="text" value={value} onChange={handleChange} />
</React.Fragment>
);
};
TextField.propTypes = {
/**
* Text to use as a label
*/
label: PropTypes.string,
/**
* Value controlled externally to component
*/
value: PropTypes.string,
/**
* Change handler
*/
onChange: PropTypes.func,
};
TextField.defaultProps = {};
Story:
import React from 'react';
import { useArgs } from '@storybook/client-api';
import { TextField } from './TextField';
export default {
title: 'Controlled TextField',
component: TextField,
argTypes: {},
};
const Template = (args) => {
const [_args, updateArgs] = useArgs();
const handleChange = (value) => updateArgs({ value });
return <TextField {...args} onChange={handleChange} />;
};
export const Basic = Template.bind({});
Basic.args = {
value: 'foo',
label: 'Lorem ipsum',
};
System:
Please paste the results of npx -p @storybook/cli@next sb info here.
Environment Info:
(node:73572) UnhandledPromiseRejectionWarning: TypeError: e.filter is not a function
at /Users/jcq/.npm/_npx/73241/lib/node_modules/@storybook/cli/node_modules/envinfo/dist/envinfo.js:1:73205
at async Promise.all (index 6)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:73572) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:73572) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
😅
I’m using @storybook/* 6.0.0-rc.14 with latest create-react-app.
Additional context I’ve created a repo that demonstrates the issue
Issue Analytics
- State:
- Created 3 years ago
- Reactions:11
- Comments:14 (7 by maintainers)

Top Related StackOverflow Question
@tmeasday Turning on
features.modernInlineRenderin.storybook/main.tsimmediately solves this issue, as you predicted above:Story is rendered as expected without any unmouting cycle at args update 👌
This hasn’t been fixed yet in 6.3.4. I think the reason is that
updateArgstriggers a re-render of the args table, which is in the same container as the story, causing that one to be re-rendered too, which causes the focus to be lost.As proof I tried adding:
Then the story is rendered in an iframe, which makes the
updateArgswork, but then a change of the controls doesn’t update the story. The reason this doesn’t happen in the canvas is because the addons-drawer is not in the same container as the story.