简体   繁体   中英

Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>

Please I'm new to react. I'm trying to render data from my backend using react axios and hooks. I keep on getting this error message and I ensured the App was wrapped in a provider. Do I have to wrap the Homescreen component in a provider before exporting it? Thanks.

This is the Homescreen.js; To display the data

import React, { useEffect} from 'react';
import {Link} from 'react-router-dom'
import { useSelector } from 'react-redux/lib/hooks/useSelector';
import { useDispatch } from 'react-redux/lib/hooks/useDispatch';
import { listProducts } from '../actions/productActions';
import {Provider }from 'react-redux'; 
function HomeScreen (props) {


        const productList = useSelector(state => state.productList); 
        const { products, loading, error} = productList;

        const dispatch = useDispatch();
        useEffect(()=>{

            dispatch(listProducts()); 



            return ()=> {
                //
            };
        }, [ dispatch ])

     return loading? <div> loading... </div>:
        error? <div> {error} </div>:
        (

                    <ul className="products"> 

                    {
                      products.map(product => 

                    <li  key = {product._id} >

                            <div className="product">
                            <Link to= {'/product/'+ product._id}> 
                            <img src={product.image} className="product-image" alt="product"></img>
                             </Link> 

                                <div className="product-name"> 
                                <Link to= {'/product/'+ product._id}> {product.name} </Link> 

                                    </div>
                                <div className="product-brand"> {product.brand}</div>
                                <div className="product-price"> ${product.price}</div>
                                <div className="rating"> {product.price} Stars ({product.numReviews} Reviews)</div>
                            </div>
                        </li>
                      )
                    }

                </ul>
        )

}


export default   HomeScreen; 

This is the App;

import React from 'react';
import {Link, BrowserRouter ,Route } from 'react-router-dom'
import './App.css';
import HomeScreen from './screens/HomeScreen'
import ProductScreen from './screens/ProductScreen'
import {Provider }from 'react-redux'; 

function App() {

  const openMenu = ()=>{

      document.querySelector(".sidebar").classList.add("open")
  }

  const closeMenu = ()=>{
    document.querySelector(".sidebar").classList.remove("open")
  }
  return (

    <BrowserRouter> 
    <div className="grid-container">
            <header className="header">
                <div className="brand"> 
                    <button onClick={openMenu}>
                        &#9776;
                    </button>
                    <Link to = "/">Amazone</Link>

                </div>
                <div className="header-links"> 
                    <a href="/#"> Cart </a>
                    <a href="/#"> SigniN</a>
                </div>
             </header>
            <aside className="sidebar"> 
                <h3> Shopping Categories</h3>
                <button className="sidebar-close-button" onClick={closeMenu}>X </button>
                <li>
                    <a href="index.html"> Pants</a>
                </li>

                <li>
                    <a href="index.html"> Shirts</a>
                </li>
            </aside>

        <main className="main">
            <div className="content">
            <Route path="/product/:id" component = {ProductScreen} /> 
           <Route path="/" exact = {true} component = {HomeScreen} />   


            </div>

        </main>

        <footer className="footer">
            All Rights Reserved
        </footer>

    </div>
    </BrowserRouter>
  );
}
export default App;

This is the Index.js

import React from 'react';
import {Provider }from 'react-redux';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import allreducer from './allreducer.js'
import thunk from 'redux-thunk';
import {createStore, applyMiddleware, compose} from 'redux';


// to see the action dispatched in the state at the browser
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const initialState = {};
//Thunk is a middleware that allows operation of async in the action
const store = createStore(allreducer, initialState, composeEnhancer(applyMiddleware(thunk)));

ReactDOM.render(
  <Provider store={store}> 

     <App />

  </Provider>
 ,

  document.getElementById('root')
);
serviceWorker.unregister();

The Reducer:

import { PRODUCT_LIST_REQUEST, PRODUCT_LIST_SUCCESS, PRODUCT_LIST_FAIL, PRODUCT_DETAILS_REQUEST, PRODUCT_DETAILS_SUCCESS, PRODUCT_DETAILS_FAIL } from "../constants/productConstants";

//Reducers 
function productListReducer (state = {product: []}, action){

    switch(action.type){
        case PRODUCT_LIST_REQUEST:
            return {loading: true};
        case PRODUCT_LIST_SUCCESS:
            return {loading: false, products: action.payload}
        case PRODUCT_LIST_FAIL:
            return {loading:false, error: action.payload}
        default:
            return state;      
    }
}

Reducer Constants;

export const PRODUCT_LIST_REQUEST = 'PRODUCT_LIST_REQUEST';
export const PRODUCT_LIST_SUCCESS = 'PRODUCT_LIST_SUCCESS';
export const PRODUCT_LIST_FAIL = 'PRODUCT_LIST_FAIL';

export const PRODUCT_DETAILS_REQUEST = 'PRODUCT_DETAILS_REQUEST';
export const PRODUCT_DETAILS_SUCCESS = 'PRODUCT_DETAILS_SUCCESS';
export const PRODUCT_DETAILS_FAIL = 'PRODUCT_DETAILS_FAIL';

Reducer Action;

import { PRODUCT_LIST_REQUEST, PRODUCT_LIST_SUCCESS, PRODUCT_LIST_FAIL, PRODUCT_DETAILS_REQUEST, PRODUCT_DETAILS_SUCCESS, PRODUCT_DETAILS_FAIL } from "../constants/productConstants";

//Reducers 
function productListReducer (state = {product: []}, action){

    switch(action.type){
        case PRODUCT_LIST_REQUEST:
            return {loading: true};
        case PRODUCT_LIST_SUCCESS:
            return {loading: false, products: action.payload}
        case PRODUCT_LIST_FAIL:
            return {loading:false, error: action.payload}
        default:
            return state;      
    }
}

The issue is that you're importing your hooks from 'react-redux/lib/hooks/useSelector' instead of 'react-redux'.

Instead of:

import { useSelector } from 'react-redux/lib/hooks/useSelector';
import { useDispatch } from 'react-redux/lib/hooks/useDispatch';

use:

import { useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM