web-dev-qa-db-ja.com

JestJS->不変の違反:「Connect(Portfolio)」のコンテキストまたは小道具のいずれにも「ストア」が見つかりませんでした

完全なエラーメッセージ:

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

アプリが動作しているときにJestテストでこのエラーが発生する理由がわかりません。また、ディスパッチアクションで状態を変更できます。

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware, compose } from 'redux'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import reducer from './reducer'
import App from './App'

const element = document.getElementById('coinhover');

const store = createStore(reducer, compose(
    applyMiddleware(thunk),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
));

ReactDOM.render(
    <Provider store={ store }>
        <App />
    </Provider>, element);

ポートフォリオコンポーネント

import React from 'react'
import { connect } from 'react-redux'
import SocialMediaFooter from '../common/SocialMediaFooter'
import AssetsTable from '../assetsTable/AssetsTable'
import local_coins from '../../coins.json'
import * as api from '../../services/api'

const mapStateToProps = ({ portfolio }) => ({
    portfolio
});

let localCoins = local_coins;

class Portfolio extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            loading: true,
            assets: props.portfolio,
            total: 0
        };
    }

    componentDidMount() {
        this.setState({ loading: false });
    }

    render() {
        const assets = this.state.assets;
        const total  = this.state.total;

        return (
            <div className="app-bg">
                <section className="portfolio">
                    <header>
                        <h1><span className="plus">+</span>COINHOVER</h1>
                        <h2>Watch your cryptocurrency asset balances in once place.</h2>
                        <em className="num">${ total }</em>
                    </header>
                    { this.state.loading ? (
                        <div className="loading">
                            <div className="loader"></div>
                            <span>Loading coin data...</span>
                        </div>
                    ) : (
                        <AssetsTable assets={ assets }/>
                    )}
                    <SocialMediaFooter />
                </section>
            </div>
        )
    }
}

export default connect(mapStateToProps, null)(Portfolio)
8
Leon Gaban

エラーメッセージに従って、接続されたコンポーネントのテストが実際にストアインスタンスにアクセスできることを確認する必要があります。したがって、テストコードでは、<Provider store={store}><ConnectedPortfolio /></Provider>または<ConnectedPortfolio store={store} />も使用する必要があります。または、プレーンなPortfolioコンポーネントを個別にエクスポートして、接続されたバージョンではなく、それをテストすることもできます。

詳細については テストに関するReduxドキュメント 、および React/ReduxリンクリストReduxテストアプローチ に関する記事を参照してください。

5
markerikson

私は同じ問題に遭遇しました、これが私がそれを修正した方法です:reduxの公式 docs が示唆するように、接続されていないコンポーネントもエクスポートする方が良いです。

デコレータを処理せずにAppコンポーネント自体をテストできるようにするには、装飾されていないコンポーネントもエクスポートすることをお勧めします。

import { connect } from 'react-redux'

// Use named export for unconnected component (for tests)
export class App extends Component { /* ... */ }
 
// Use default export for the connected component (for app)
export default connect(mapStateToProps)(App)

デフォルトのエクスポートはまだ装飾されたコンポーネントであるため、上の図のインポートステートメントは以前と同じように機能し、アプリケーションコードを変更する必要はありません。ただし、次のように、装飾されていないアプリコンポーネントをテストファイルにインポートできるようになりました。

// Note the curly braces: grab the named export instead of default export
import { App } from './App'

そして、両方が必要な場合:

import ConnectedApp, { App } from './App'

アプリ自体では、通常どおりインポートします。

import App from './App'

名前付きエクスポートはテストにのみ使用します。

1
Vishal Gulati