web-dev-qa-db-ja.com

"Connect()"のプロップとしてストアを明示的に渡す方法

私のReactコンポーネントをテストして、次のエラーを取得しようとしています。

不変の違反:「Connect()」のコンテキストまたは小道具のいずれにも「ストア」が見つかりませんでした。ルートコンポーネントを<Provider>でラップするか、明示的に「store」をプロップとして「Connect()」に渡します。

テストでコンポーネントをレンダリングしているときにエラーが発生します。

beforeEach(() => {
  Component = TestUtils.renderIntoDocument(<SideMenu />);
});

ページ上でコンポーネントをレンダリングするときにうまく機能します。ただし、テストでは、ストアをコンポーネントに明示的に渡すことができません。

誰かが正しい方向を指すことができますか?

18
Salman

connectreact-reduxによって提供されるデコレータです。 reduxへのconnectedコンポーネントはスマートコンポーネントであり、propを介して、またはProviderを介してエラーメッセージが示すように、ストアが使用可能であると想定しています。

スマートコンポーネントのテスト中に、モックストアをpropとして提供できます。ただし、storeを期待している別の子コンポーネントがある場合、propの方法は機能しません。

storeをサブスクライブする子コンポーネントをimportsするコンポーネントにstoreを提供する方法は次のとおりです。

const initialState = {key: 'value'};
const store = createStore(initialState);

component = TestUtils.renderIntoDocument(
  <Provider store={store(initialState)}>
    {() => <SideMenu />}
  </Provider>
);
5
Salman

質問に答えるには(私はこれに遭遇し、受け入れられた答えは私が必要としたものではありません)、次のような新しいメソッドを作成します。

function connectWithStore(store, WrappedComponent, ...args) {
  let ConnectedWrappedComponent = connect(...args)(WrappedComponent)
  return function (props) {
    return <ConnectedWrappedComponent {...props} store={store} />
  }
}

次に、接続するには次を使用します:

const ConnectedApp = connectWithStore(store, App, mapStateToProps, mapDispatchToProps,)

export default ConnectedApp;

ここを参照してください: https://github.com/reactjs/react-redux/issues/390#issuecomment-221389608

5
mikeb

ほとんどの場合、テストでコンポーネント自体をインポートすると問題なく動作することがわかりました。

SideMenu.js:

export class SideMenu extends React.Component {
 // implementation
}

export default connect(mapStateToProps,)(SideMenu)

SideMenu.spec.js:

import { SideMenu } from 'path/to/SideMenu.js'

const props = {
  // provide all necessary stubs and mocks for redux props and actions 
}
component = TestUtils.renderIntoDocument(<SideMenu {...props} />);

注:Салманが指摘したように、この方法は、storeを期待する別の子コンポーネントがある場合には機能しません。

2
Yevgen Safronov