Skip to content

Commit

Permalink
Merge pull request #12781 from storybookjs/feature/reactStrictModeOption
Browse files Browse the repository at this point in the history
React: Add strictMode option
  • Loading branch information
shilman committed Oct 16, 2020
2 parents 9eeed16 + 69df720 commit 2b9ff49
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 9 deletions.
17 changes: 9 additions & 8 deletions app/react/src/client/preview/render.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { document } from 'global';
import React, { Component, FunctionComponent, ReactElement, StrictMode } from 'react';
import { document, FRAMEWORK_OPTIONS } from 'global';
import React, { Component, FunctionComponent, ReactElement, StrictMode, Fragment } from 'react';
import ReactDOM from 'react-dom';

import { RenderContext } from './types';
Expand All @@ -8,11 +8,7 @@ const rootEl = document ? document.getElementById('root') : null;

const render = (node: ReactElement, el: Element) =>
new Promise((resolve) => {
ReactDOM.render(
process.env.STORYBOOK_EXAMPLE_APP ? <StrictMode>{node}</StrictMode> : node,
el,
resolve
);
ReactDOM.render(node, el, resolve);
});

class ErrorBoundary extends Component<{
Expand Down Expand Up @@ -47,6 +43,8 @@ class ErrorBoundary extends Component<{
}
}

const Wrapper = FRAMEWORK_OPTIONS?.strictMode ? StrictMode : Fragment;

export default async function renderMain({
storyFn,
showMain,
Expand All @@ -56,12 +54,15 @@ export default async function renderMain({
// storyFn has context bound in by now so can be treated as a function component with no args
const StoryFn = storyFn as FunctionComponent;

const element = (
const content = (
<ErrorBoundary showMain={showMain} showException={showException}>
<StoryFn />
</ErrorBoundary>
);

// For React 15, StrictMode & Fragment doesn't exists.
const element = Wrapper ? <Wrapper>{content}</Wrapper> : content;

// We need to unmount the existing set of components in the DOM node.
// Otherwise, React may not recreate instances for every story run.
// This could leads to issues like below:
Expand Down
1 change: 1 addition & 0 deletions app/react/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ import { StorybookConfig as BaseConfig } from '@storybook/core/types';
export interface StorybookConfig extends BaseConfig {
reactOptions?: {
fastRefresh?: boolean;
strictMode?: boolean;
};
}
1 change: 0 additions & 1 deletion examples/official-storybook/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
DOTENV_DISPLAY_WARNING=none
STORYBOOK_EXAMPLE_APP=true
1 change: 1 addition & 0 deletions examples/official-storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = {
],
reactOptions: {
fastRefresh: true,
strictMode: true,
},
addons: [
{
Expand Down
2 changes: 2 additions & 0 deletions lib/core/src/server/preview/iframe-webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default async ({
}) => {
const dlls = await presets.apply('webpackDlls', []);
const logLevel = await presets.apply('logLevel', undefined);
const frameworkOptions = await presets.apply(`${framework}Options`, {}, {});
const { raw, stringified } = loadEnv({ production: true });
const babelLoader = createBabelLoader(babelOptions, framework);
const isProd = configType === 'PRODUCTION';
Expand Down Expand Up @@ -157,6 +158,7 @@ export default async ({
new DefinePlugin({
'process.env': stringified,
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
FRAMEWORK_OPTIONS: frameworkOptions,
}),
isProd ? null : new WatchMissingNodeModulesPlugin(nodeModulesPaths),
isProd ? null : new HotModuleReplacementPlugin(),
Expand Down

0 comments on commit 2b9ff49

Please sign in to comment.