1

I've seen many answer on this website and in official docs and many other places. But I couldn't able to achieve results. That's why I'm posting this question.

SO, my question is I have 3 files named: App.js, SignUp.js and Welcome.js.

My task is to get value in form from SignUp.js page and print that value to the Welcome.js component. I read about lifting state up and higher order components but couldn't able to do it.

Any help is appreciated.

Here's my code:

App.js:

import React,{Component} from "react";
import {BrowserRouter as Router, Link, Switch, Route} from "react-router-dom";
import SignUp from './SignUp';
import Welcome from './Welcome';
class App extends Component {
  render(){
    var homeMessage = () =>{
      return(<div><SignUp /></div>);
    }
    return(
    <Router>
      <div>
        <Route exact path="/src/Welcome" component={Welcome}/>
        <Route exact path="/" component={homeMessage}/>
      </div>
    </Router>
    );
  }
}
export default App;

SignUp.js;

import React,{Component} from "react";
import {Link} from "react-router-dom";
export default class SignUp extends Component {
  constructor(props){
    super(props);

    this.state = {
      firstName:''
    };
  }
  inputData = event =>
  {
    this.setState({
      [event.target.name]:event.target.value
    });
  }
  submitData = event =>
  {
    event.preventDefault();
  }
  render(){
    return(
      <div>
        <form onSubmit={this.submitData}>
          <input type="text" name="firstName" onChange={this.inputData}/>
          <button type="submit"> Submit</button>
        </form>
        <Link to="/src/Welcome">Welcome</Link>
      </div>
    );
  }
}

Welcome.js:

    import React,{Component} from "react";
    import SignUp from './SignUp';
    export default class Welcome extends Component {
      render(){
        return(
          <div>
            {this.state.firstName}
          </div>
        );
      }
    }

"And please give answer if possible then in react-way only not redux or any other library. Because as per Dan Abramov article "Thinking in React" so first I want to try all scope which is available in react only."

1 Answers1

0

Pass the data back to the parent from SignUp component and then pass it as a prop to the Welcome component. The other way is to store the SignUp component state in the App component so that you don't need to pass it back up when you submit.

App.js

import React,{Component} from "react";
import {BrowserRouter as Router, Link, Switch, Route} from "react-router-dom";
import SignUp from './SignUp';
import Welcome from './Welcome';


class App extends Component {
  state = {
     firstName: ''
  }
  onSignIn = (value) => {
      this.setState({firstName: value});
  }
  render(){

    return(
    <Router>
      <div>
        <Route exact path="/src/Welcome" render={(props) => <Welcome firstName={this.state.firstName} {...props}/>}/>
        <Route exact path="/" render={(props) =>{
   return(<div><SignUp onSignIn={this.onSignIn} {...props} /></div>);
}}/>
      </div>
    </Router>
    );
  }
}
export default App;

SignUp.js

export default class SignUp extends Component {
  constructor(props){
    super(props);

    this.state = {
      firstName:''
    };
  }
  inputData = event =>
  {
    this.setState({
      [event.target.name]:event.target.value
    });
  }
  submitData = event =>
  {
    event.preventDefault();
    this.props.onSignIn(this.state.firstName);
  }
  render(){
    return(
      <div>
        <form onSubmit={this.submitData}>
          <input type="text" name="firstName" onChange={this.inputData}/>
          <button type="submit"> Submit</button>
        </form>
        <Link to="/src/Welcome">Welcome</Link>
      </div>
    );
  }
}

Welcome.js

import React,{Component} from "react";
import SignUp from './SignUp';
export default class Welcome extends Component {
  render(){
    return(
      <div>
        {this.props.firstName}
      </div>
    );
  }
}

Some useful links:

How to pass data from child component to its parent in ReactJS?

Passing custom props to router component in react-router v4

ReactJS - Lifting state up vs keeping a local state

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • I got some error please look at it... @Shubhum Katri –  Mar 15 '18 at 11:21
  • TypeError: _this.props.onSignIn is not a function. (In '_this.props.onSignIn(_this.state.firstName)', '_this.props.onSignIn' is undefined) –  Mar 15 '18 at 11:22
  • @YChoksi updated the answer, please check. home did not have this.onSignIn defined – Shubham Khatri Mar 15 '18 at 12:25
  • In parent component you wrote only state and in child component you wrote this.state why? And other thing is that if I'm having many state variables like 14-15 and required at many deep places. Will this approach is good? –  Mar 15 '18 at 12:28
  • 1
    @YChoksi, both of them are one and the same thing, in the parent the state is defined like class fields, whereas in child its defined in the constructor, you can follow either of these – Shubham Khatri Mar 15 '18 at 12:29
  • Check this https://stackoverflow.com/questions/45832853/initialise-state-as-a-class-property-or-in-constructor-reactjs/45833026#45833026 – Shubham Khatri Mar 15 '18 at 12:31
  • @ShubhumKhatri. And other thing is that if I'm having many state variables like 14-15 and required at many deep places. Will this approach is good? –  Mar 15 '18 at 12:33
  • YChoksi, Its better to define the state in the common parent and then propogate a handler and the state down. Kindly check the answer about Lifting state up that I linked in my answer – Shubham Khatri Mar 15 '18 at 12:36
  • Hey Shubhum, I read all 3 articles of yours which you mentioned in links below your answer. And as per my understanding I think to get more cleaner and efficient code I think redux will be better approach. Thanks for help.. –  Mar 23 '18 at 04:33