skip to Main Content

I am using nextjs along with react redux.

I am getting this error:

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

I have tried everything and have also wrapped it in a provider yet the error still persists.

import { useRouter } from 'next/router';
import { useState } from 'react'
import axios from 'axios'
import { useDispatch } from "react-redux";
import { authActions } from '../store';
import { Provider } from 'react-redux'
import store from '../store';

export default function Signup(props) {
    const router = useRouter();
    const dispatch = useDispatch();

    const [inputs, setInputs] = useState({
        name: "", email: "", password: ""
    });

    const handleChange = (e) => {
        setInputs((prevState) => ({
            ...prevState,
            [e.target.name]: e.target.value
        }))
    }

    const sendRequest = async (type = "signup") => {
        const res = await axios.post(`https://blog-app-23.onrender.com/api/user/${type}`, {
            name: inputs.name,
            email: inputs.email,
            password: inputs.password
        }).catch((err) => console.log(err));
        const data = await res.data;
        return data;
    }

    const handleSubmit = (e) => {
        e.preventDefault()
        console.log(inputs);
        sendRequest("signup")
            .then((data) => localStorage.setItem("userId", data.user._id))
            .then(() => dispatch(authActions.login()))
            .then(() => router.push("/courses"))
    }
    return (
        <Provider store={store}>
            <section>
                <div className='h-[100vh] flex items-center'>
                    <ReactNebula className="nebula" config={{ astres: smallSolarSystem }} />
                    <div className='w-1/2 h-[30rem]'><ComputersCanvas /></div>
                    <div className='w-1/2 h-[10rem] stu flex items-center'>
                        <div className='h-[30rem] w-[29rem] rounded-3xl bg-white stu flex mx-auto p-6 flex-col'>
                            <h1 className='text-2xl font-semibold'>Sign Up</h1>
                            <div className='mt-5 flex flex-col'>
                                <form onSubmit={handleSubmit}>
                                    <input name="name" onChange={handleChange} value={inputs.name} placeholder='name' className="py-2 my-3 px-5 ml-2 rounded-md bg-gray-200 text-gray-700 flex-grow mr-4" />
                                    <input name="email" onChange={handleChange} value={inputs.email} type={'email'} placeholder='email' className="py-2 my-3 px-5 ml-2 rounded-md bg-gray-200 text-gray-700 flex-grow mr-4" />
                                    <input name="password" onChange={handleChange} value={inputs.password} type={'password'} placeholder='password' className="py-2 my-3 px-5 ml-2 rounded-md bg-gray-200 text-gray-700 flex-grow mr-4" />
                                    <button type={"submit"} className=' mt-7 started text-white py-3 px-5 text-md rounded-2xl bg-red-500' >Sign Up</button>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
        </Provider>
    )
}

I tried everything and the code didn’t work.

2

Answers


  1. You’re using useDispatch() outside of <Provider>, because <Provider> is currently contained inside <Signup>‘s markup.

    Move Signup‘s contents inside a separate component (named WithProvider below) 1:

    // imports...
    
    export default function Signup(props) {
      return (
        <Provider store="store">
          <WithProvider {...props} />
        </Provider>
      )
    }
    function WithProvider(props) {
      // you can `useDispatch()` here because it's inside `<Provider>`
    }
    

    1 – You can name it WithStore or whatever else you want; it’s a local function. The default export is still <Signup>.

    Login or Signup to reply.
  2. The Signup component can’t access any redux context since it’s the component rendering the redux context. Promote Provider higher in the ReactTree than any component that needs to access the context it provides. In this case you can simply wrap Signup in the Provider component and it can use the useDispatch hook.

    Example:

    <Provider store={store}> // <-- provides redux context to sub-ReactTree
      ...
      <Signup />
      ...
    </Provider>
    
    export default function Signup(props) {
      const router = useRouter();
      const dispatch = useDispatch(); // <-- can access redux context now
    
      ...
    
      return (
        <section>
          ...
        </section>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search