简体   繁体   中英

React and methods within child components

I'm trying to learn React. In my App.jsx, I have setup my routes. And they work. One of my components is a sign in component. When I click the sign in button, I need to fire an even on the App. So, I created a function, and want to pass a parameter to the SignIn component, so that I can call the event from sign in. But I'm unsure how to pass the function to the component using routes.

export default class App extends React.Component {

    handleLogin() {
        console.log("Ahhhh")
    }

    render() {
        return (
            <div>
                <Router>
                    <div>
                        <Route exact path='/' component={Home} />
                        <Route path='/about' component={About} />
                        <Route path='/contact' component={Contact} />
                        <Route path="/signin" component={SignIn} />
                        <Route path="/register" component={Register} />
                    </div>
                </Router>
                <Footer />

            </div>
        )
    }
}

My sign in page is just:

export default class SignIn extends Component {
    render() {
        return (
            <div>
            <Navbar />
            <div className="row justify-content-md-center">
                <div className="col-lg-4">
                    <SignInBox  /> 
                </div>
            </div>   
            </div>
        )
    }
}

Here I think I can use props to get the method, and then pass it to my Signin Box.

My signin box is the form, and here, I want to pass the username and password back to the App to validate. I need to get it to App, as I want to then update my navbar to hide the login button, and show a Logout button.

export default class SignInBox extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: '',
            password: '',
            rememberme: true
        }

        this.handleSignin = this.handleSignin.bind(this);
    }

    handleSignin(event) {
        event.preventDefault();

        this.setState(
            {
                username: this.refs.username.value,
                password: this.refs.password.value
            }, () => console.log(this.state)
        );
    }

    render() {
        return (
            <div>
                <div className="container">
                    <div className="form-signin">
                        <control-label for="inputEmail" className="sr-only">Email address</control-label>
                        <input type="email" ref="username" id="inputEmail" className="form-control" placeholder="Email address" required autoFocus />
                        <control-label for="inputPassword" className="sr-only">Password</control-label>
                        <input type="password" ref="password" id="inputPassword" className="form-control" placeholder="Password" required />
                        <div className="checkbox">
                            <control-label>
                                <input type="checkbox" /> Remember me
                            </control-label>
                        </div>
                        <button className="btn btn-lg btn-primary btn-block" type="button" onClick={this.handleSignin}>Sign in</button>
                        <div className="footer-text"><Link to="/"> Forgotten Password?</Link></div>
                    </div>
                </div>
            </div>
        );
    }
}

I think it's wrong to have the sign in method in the App, as it should be confined to the Singin page - but how can I then update the navbar? The App.jsx is the parent of all components.

(Working code: https://github.com/CraigInBrisbane/ReactLearning )

How should I handle this.

Instead of using component use render , check the DOC for difference.

Pass the function like this:

<Route 
    path="/signin" 
    render={props => <SignIn validate={this._validate} {...props} />} 
/>

And inside SignIn component, you can access function by this.props.validate()

Suggestion : Better approach would be to use redux/flux for data management, it will help you to pass and access data of different pages and in various other scenarios also.

Check Redux Docs .

You can send a function from the Parent like this:

class App extends Component{
    constructor(props){
        super(props);
        this.someFn = this.someFn.bind(this);
    }
    function someFn(data){
        ...do something...
    }
    render(){
        return(
          <div>
              <Route path="/example" render={() => {
                    <Child someFn={this.someFn} />;
                }} />
           </div>
        )
     }
}

And the child component is as follows:

class Child extends Component{
    render(){
       <div onClick={this.props.someFn(this, data)}>

       </div>
    }
}

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