Sunwoo Jeong
Sunwoo Jeong

Reputation: 117

React context API and Router

I am trying to use context API with the React-router, but it is not working as I expect.

this is my Container.js file

import React from "react"
import {Route, Switch} from "react-router-dom";

import Home from "../Components/Home/home";
import Create from "../Components/Create/create";
import Login from "../Components/Login/login";
import {GoogleIdContextProvider} from "../Context/googleIdContext";

const Container = () => {
    
    return (
        <GoogleIdContextProvider>
            <Switch>
                <Route exact path = "/home" component = {Home} />
                <Route exact path = "/create" component = {Create} />
                <Route path = "/" component = {Login} />
            </Switch>
        </GoogleIdContextProvider>
    )
}

export default Container;

This is login.js file

import React, {useState, useContext} from "react"
import GoogleLogin from "react-google-login";

import {GoogleIdContext} from "../../Context/googleIdContext"



const Login = (props) => {

    const [googleId, setGoogleId] = useContext(GoogleIdContext);

    const test = res => {
        console.log(res.profileObj.googleId);
    }

    const success = res => {
        console.log(res.profileObj);
        setGoogleId(res.profileObj.familyName) //my family name is "jeong"
    }

    return (
        <div>
            <GoogleLogin 
                clientId = "secret!!"
                buttonText = "GoogleLogin"
                onSuccess = {success}
                onFailure = {test}
                cookiePolicy={'single_host_origin'}
            />
            {googleId}
        </div>
    )
}

export default Login;

and this is my home.js file

import React, {useContext} from "react";

import {GoogleIdContext} from "../../Context/googleIdContext";
 
const Home = () => {
    const [googleId] = useContext(GoogleIdContext);

    console.log(googleId);
    
    return (
        <div>
            {googleId}
        </div>
    )
}

export default Home;

and finally, it is my googleIdContext.js file:

import React, {useState, createContext} from "react"

export const GoogleIdContext = createContext();

export const GoogleIdContextProvider = props => {
    const [googleId, setGoogleId] = useState("placeholder");
    return (
        <GoogleIdContext.Provider value = {[googleId, setGoogleId]}>
            {props.children}
        </GoogleIdContext.Provider>
    )
}

My expectation was the following: when I run the app with "npm run start", Step 1: I first see the login.js jsx file with the router "localhost:3000". It has the goolgle login button and placeholder, which is the value of the variable "googleId" in googleIdContext.js.

Step 2: After I login, the success function in login.js is executed, which changes the value of googleId variable with the following code: "setGoogleId(res.profileObj.familyName)"

Step 3: the word "placeholder" has been changed to "jeong", which is the family Name"

Step 4: If I move to the different route "localhost:3000/home", the home.js shows the word "jeong" insteand of "placeholder" because the value of the variable "googleId" has been changed from "placeholder" to "jeong" in Step 2.

Things went well from step 1 to 3. However, in step 4 (when changing the router), the value is not changed and still shows "placeholder" instead of "jeong", even if the value is changed in the original router.

Could anyone please explain me why the "localhost:3000/home" router still shows the "placeholder" and how I should write the code to achieve step4?

Here is the screenshot for better understanding.

localhost:3000

localhost:3000/home

Upvotes: 0

Views: 3824

Answers (2)

Michael
Michael

Reputation: 131

You need to figure out how react-router-dom works: https://reactrouter.com/.

I guess the mistake is in step 4. The result is depend on how you get to localhost:3000/home.

  1. If you register and put 'jeong' into the Context and then go to '/home' with history.push('/home') it works properly as you expect.
  2. But if you just type in url localhost:3000/home you'll get what you have now.

The difference is that in (1) you have the Context on the moment of navigation, but in (2) this Context hasn't just existed: https://photos.app.goo.gl/mJZsceMAgek6ABLT7.

To solve this you have to check in your root component if the user is registered and put his data to your Context, something like:

useEffect(() => {
const data = checkRegistration();
if (data.registered) {
  setContext(data.userName)
}}, []);

Upvotes: 0

Cem Nisan
Cem Nisan

Reputation: 107

When using a router, you must use the router structure that includes the switch and the route.

<GoogleIdContextProvider>
          <Router>
            <Switch>
                <Route exact path = "/home" component = {Home} />
                <Route exact path = "/create" component = {Create} />
                <Route path = "/" component = {Login} />
            </Switch>
          </Router>
 </GoogleIdContextProvider>

Don't forget to import the router! --> import {BrowserRouter as Router} from 'react-router-dom'

Upvotes: 3

Related Questions