Redux + storybook выдает предупреждение о смене магазина на лету даже при использовании module.hot
Я использую сборник рассказов, и я хочу добавить излишний в качестве декоратора. Когда я запускаю сборник рассказов, я получил предупреждение в консоли:
<Provider> does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions.
Это мой код для сборника рассказов:
/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */
import React from 'react';
import { configure, storiesOf } from '@storybook/react';
import { Provider as ReduxProvider } from 'react-redux';
import forEach from 'lodash/forEach';
import unset from 'lodash/unset';
import Provider from 'components/Provider';
import initStore from 'utils/initStore';
import messages from '../lang/en.json';
const req = require.context('../components', true, /_stories\.js$/);
const ProviderDecorator = (storyFn) => {
const TheProvider = Provider(() => storyFn());
return (
<ReduxProvider store={initStore()}>
<TheProvider key={Math.random()} now={1499149917064} locale="en" messages={messages} />
</ReduxProvider>
);
}
function loadStories() {
req.keys().forEach((filename) => {
const data = req(filename);
if (data.Component !== undefined && data.name !== undefined && data.stories !== undefined) {
const Component = data.Component;
const stories = storiesOf(data.name, module);
stories.addDecorator(ProviderDecorator);
let decorator = data.stories.__decorator;
if (data.stories.__decorator !== undefined) {
stories.addDecorator((storyFn) => data.stories.__decorator(storyFn()));
}
forEach(data.stories, (el, key) => {
if (key.indexOf('__') !== 0) {
stories.add(key, () => (
<Component {...el} />
));
}
});
} else {
console.error(`Missing test data for ${filename}!`)
}
});
}
configure(loadStories, module);
и файл initStore:
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunkMiddleware from 'redux-thunk';
import { persistStore, autoRehydrate } from 'redux-persist';
import reducers from 'containers/redux/reducers';
export default () => {
const store = createStore(
reducers,
{},
composeWithDevTools(applyMiddleware(thunkMiddleware), autoRehydrate()),
);
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../containers/redux/reducers', () => {
const nextReducers = require('../containers/redux/reducers'); // eslint-disable-line global-require
store.replaceReducer(nextReducers);
});
}
persistStore(store);
return store;
};
Итак, как вы можете видеть, я следовал инструкциям по ссылке в предупреждении. Что я сделал не так и как я могу удалить это предупреждение? Я знаю, что это не будет отображаться на рабочем сервере, но это довольно раздражает в режиме разработки.:/
1 ответ
Причина, по которой это происходит, связана с горячей загрузкой Storybook.
Когда вы изменяете свою историю, этот модуль загружается в горячем режиме, что означает, что код внутри него выполняется снова.
Поскольку вы используете функцию создания хранилища, а не экземпляр хранилища из другого модуля, фактический объект хранилища, который передается ReduxProvider
на горячей загрузке каждый раз новое.
Однако дерево React, которое реконструируется, по большей части идентично, а это означает, что ReduxProvider
Экземпляр перерисовывается с новыми реквизитами, а не создается заново.
По сути, это меняет свой магазин на лету.
Решить, чтобы убедиться, что ReduxProvider
Экземпляр тоже новый, при горячей загрузке. Это легко решить, передав ему уникальный key
опора, например:
const ProviderDecorator = (storyFn) => {
const TheProvider = Provider(() => storyFn());
return (
<ReduxProvider key={Math.random()} store={initStore()}>
<TheProvider key={Math.random()} now={1499149917064} locale="en" messages={messages} />
</ReduxProvider>
);
}
Из React Keys:
Клавиши помогают React определить, какие элементы были изменены, добавлены или удалены. Ключи должны быть даны элементам в массиве, чтобы дать элементам устойчивую идентичность.