简体   繁体   中英

Set value of prop in child component and pass value back to state of app.js, react

I feel like this is pretty simple and it's just my lack of experience with react.js holding me up, but I have my app.js file which has a state value isUserLoggedIn and I'm passing this into my Login.js file as a prop.

The values is getting to the login page because I can use a conditional there to render or console.log accordingly.

However, I can't seem to figure out how I can (using my handleSubmit function in Login.js) set the value of loggedIn in props to true and pass back to the app.js file.

I'm using this to render conditionally in app.js so all I need to do is be able to change the value of loggedIn in login.js and pass that back to app.js.

How can I do that here?

App.js

class App extends React.Component {

    state = { 

          isUserLoggedIn: false
    };




    render() {

            return (
                <Router>
                    <Row className={css(styles.container)}>
                        <Column flexGrow={1} className={css(styles.mainBlock)}>
                            <div className={css(styles.content)}>
                                <Switch>
                                    <Route path="/" exact component={(props) => <Login {...props} loggedIn = {this.state.isUserLoggedIn}/>} />
                                </Switch>
                            </div>
                        </Column>
                    </Row>
                </Router>
            );
        }
    }
}

export default App;

Login.js

import React, { useState } from "react";
    import { Button, FormGroup, FormControl, FormLabel } from "react-bootstrap";
    import "./Login.css";

    export default function Login(props) {

        const [email, setEmail] = useState("");
        const [password, setPassword] = useState("");


        function validateForm() {
            return email.length > 0 && password.length > 0;
        }

        async function handleSubmit(event) {
            event.preventDefault();

            try{
                props.history.push("/");
            }catch (e) {
                alert(e.message);
            }
        }

        return(
            <div className="Login">
                <form onSubmit={handleSubmit}>
                    <FormGroup controlId="email" bsSize="large">
                        <FormLabel>Email</FormLabel>
                        <FormControl 
                            autoFocus
                            type="email"
                            value={email}
                            onChange={e => setEmail(e.target.value)}
                        />
                    </FormGroup>
                    <FormGroup controlId="password" bsSize="large">
                        <FormLabel>Password</FormLabel>
                        <FormControl 
                            value={password}
                            onChange={e => setPassword(e.target.value)}
                            type="password"
                        />
                    </FormGroup>
                    <Button bsSize="large" disabled={!validateForm()} type="submit">
                        Login
                    </Button>
                </form>
            </div>
        );
    }

You need to pass a function from app.js to Login.js. Also in app.js, the state should be handled by the component which means you can put it in the constructor.

App.js

class App extends React.component{
    constructor(props){
        super(props);
        this.state = {
            isLoggedIn: false
        }
    }

    handleLogin = () => {
        //add your logic here

        this.setState({
            isLoggedIn: true
        })        
    }

    render(){
        <div>
            <Route path="/" exact component={(props) => <Login {...props} handleLoggedIn = {this.handleLogin}/>} />
        </div>

    }
}

Login.js

export default function Login(props) {

    async function handleSubmit(event) {
        event.preventDefault();
        this.props.handleLoggedIn()

        try{
            props.history.push("/");
        }catch (e) {
            alert(e.message);
        }
    }
    // other parts of your code
}

Between these two components, rather you are passing the state to login.js, you are passing a function downward. After the button has been clicked, the function in app.js will be triggered. Because the function set a new state, the component will re-render and hence update the component. Therefore, you are able to get the latest state.

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