Fawwaz Yusran
Fawwaz Yusran

Reputation: 1480

React: How to pass an argument to a parent component

So I have a parent component that acts like a router to all the components in my app.

In my child Login component, it generates a token if user successfully sign in, and I want this token to be passed to the parent component so that it can direct the user to the dashboard, with the token passed to that Dashboard component.

My Login's sign-in handling part:

//...
handleSubmit = event => {
    event.preventDefault();

    let username = this.state.username;
    let password = this.state.password;

    SignInAndGetToken(username, password)
      .then(response => {
        if (response.data["code"] === 200) {
          let newToken = response.data["token"];
          console.log("token = " + newToken);

          console.log("submitting with username: " + username + " pwd: " + password);
          this.props.newLogin(newToken, username)
        }
      })
      .catch(function (error) {
        console.log(error);
      })
  };
// ...

// SignInHandler.js
export const SignInAndGetToken = (username, password) =>
  Axios.post(LoginPath, {
    "username": username,
    "password": password
  });

Parent component (App.js) :

import React, {Component} from 'react';
import {Route, Switch} from "react-router";
import Home from "./components/Home";
import MyNavbar from "./components/MyNavbar";
import Register from "./components/auth/Register";
import Dashboard from "./components/dashboard/Dashboard";
import Login from "./components/auth/Login";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      token: "",
      username: ""
    }
  }

  newLogin(token, username) {
    this.setState({
      token: token,
      username: username
    })
  }

  render() {
    return (
      <React.Fragment>
        <MyNavbar/>
        <Switch>
          <Route exact path="/" component={Home}/>
          <Route path="/login" component={Login}/>
          <Route exact path="/register" component={Register}/>

          <Route path="/dashboard"
                 render={(props) =>
                   <Dashboard {...props}
                              token={this.state.token}
                              username={this.state.username}/>
                 }
          />
        </Switch>
      </React.Fragment>
    );
  }
}

export default App;

I've read this example, but it's parent function doesn't take any parameter.

Is there a way to call that newLogin(token, username) method from the Login component? Or is this logic wrong?

Upvotes: 0

Views: 420

Answers (3)

Nirav Patel
Nirav Patel

Reputation: 47

As per your code you need to pass newLogin function to login route like below code, and as i think this is not the proper way, what you have done you need to store that token in local storage so you will use that token in your entire system

<Route path="/login" render={(props) => <Login {...props} newLogin= {(token, username) => this.newLogin(token, username)} /> } />

Upvotes: 1

samo0ha
samo0ha

Reputation: 3796

all you need to do is to pass the newlogin function you defined in the parent as a prop to the child to be in the scope so, you should define the login router to refer to the Uri as a render function rather than a string component as you did in the dashboard component

<Route path="/login"
       render={(props) =>
             <Login {...props}
                    newLogin= {(token, username) => newLogin(token, username)} 
             />
      }
 />

Upvotes: 0

aqib
aqib

Reputation: 135

You can use React context api and warp your App with that Auth context so that it will be available in your whole app.

      .then(response => {
        if (response.data["code"] === 200) {
          let newToken = response.data["token"];
          console.log("token = " + newToken);

          console.log("submitting with username: " + username + " pwd: " + password);
          this.props.newLogin(newToken, username)

---------------------------------------------------------------

Here you can set this token in Auth context and as well in storage.
then redirect it to the dashboard screen using route props which is available there.

==================  *****************  ============
other approach

call callback here with tokens

        }
      })
      .catch(function (error) {
        console.log(error);
      })```


**********************************************

other approach is just pass a callback prop to this screen, as you have done with Dashboard using render function and call it with token and do stuff in App.js file. Just check for route props there*

Hope this helps



Upvotes: 0

Related Questions