重新渲染 Reactjs 后,父组件立即失去状态

Posted

技术标签:

【中文标题】重新渲染 Reactjs 后,父组件立即失去状态【英文标题】:Parent Component losing state immediately after re render Reactjs 【发布时间】:2020-12-03 04:44:31 【问题描述】:

我是 React 的新手,我正在尝试编写一个在启动时自动显示登录页面的应用程序,当用户成功登录时,父组件会更新其状态以呈现 Dashboard 组件而不是 Login .

我发现当用户登录时,它会正确更新父组件状态并显示仪表板组件一秒钟,但随后其状态再次更改并重新呈现登录组件。我认为某些原因导致状态重置,但我不确定是什么原因。

用户.js:

class User extends Component 
    constructor(props) 
        super(props);
        this.state = 
            email: '',
            isLoggedIn: false
        

        this.updateUser = this.updateUser.bind(this);
    

    updateUser(newEmail) 
        console.log(`Entered User.updateUser, email: $newEmail`);
        this.setState(
            email: newEmail,
            isLoggedIn: false
        );
    

    render() 
        if (this.state.isLoggedIn) 
            return <Dashboard/>
        

        return <Login updateTheUser=this.updateUser/>
    


export default User;

登录.js:

class Login extends Component 
    constructor(props) 
        super(props);
        this.state = 
            email: '',
            password: '',
        ;

        this.handleEmailChange = this.handleEmailChange.bind(this);
        this.handlePasswordChange = this.handlePasswordChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleResponse = this.handleResponse.bind(this);
    

    handleEmailChange(event) 
        this.setState(email: event.target.value)
    

    handlePasswordChange(event) 
        this.setState(password: event.target.value)
    

    handleResponse(res) 
        if (res.ok) 
            alert('Login Successful!');
            this.props.updateTheUser(this.state.email);
        
        else if (res.status === 401) 
            alert('Wrong Username or Password');
                
    

    async sendLoginRequest(data) 
        await fetch('http://localhost:8000/login/', 
            method: 'POST',
            headers:  'Content-Type': 'application/json',
            body: data,
        )
        .then(this.handleResponse)
        .catch(function(error) 
            alert('Server error, please try again.');
            console.error(error);
        );
    

    handleSubmit(event) 
        const data = `"email": "$this.state.email", "password": "$this.state.password"`
        this.sendLoginRequest(data);
    

    render () 
        return (
            <div id="container" className="col-md-12" align="center">
                <div id="vertical-center-div"className="col-sm-4 card bg-light">
                    <Form onSubmit=this.handleSubmit>
                        <Form.Label className="display-4 text-secondary">Login</Form.Label>
                        <Form.Group controlId="formBasicEmail">
                            <Form.Control type="email" value=this.state.email onChange=this.handleEmailChange placeholder="Email" required/>
                        </Form.Group>
                        
                        <Form.Group controlId="formBasicPassword">
                            <Form.Control type="password" value=this.state.password onChange=this.handlePasswordChange placeholder="Password" required/>
                        </Form.Group>
                        <Form.Group controlId="formBasicCheckbox">
                            <Form.Check type="checkbox" label="Remember me" />
                        </Form.Group>
                        <Button id="submitButton" variant="primary" type="submit">
                            Submit
                        </Button>
                    </Form>
                </div>
            </div>
        )
    


export default Login;

Dashboard.js:

class Dashboard extends Component 
    constructor(props) 
        super(props);
        this.state = 
            expenses: [],
            incomings: []
        
    

    render () 
        return (
            <>
            <p className="display-4">Dashboard</p>
            </>
        )
    


export default Dashboard;

【问题讨论】:

【参考方案1】:

看来,在Login.js 中,您需要使用event.preventDefault() 防止默认提交行为

handleSubmit(event) 
        event.preventDefault()
        const data = `"email": "$this.state.email", "password": "$this.state.password"`
        this.sendLoginRequest(data);
    

【讨论】:

嗨 Filip,我试过了,但它似乎阻止了表单提交请求和重新呈现登录组件 您好,我相信User.js也有错误,您将isLoggedIn设置为false 哦,好的,谢谢,所以当组件重新渲染时,它再次将isLoggedIn 设置为false?那么如何在不将其设置为 false 的情况下声明它? 我的意思是在updateUser 方法中,您将用户的电子邮件设置为newEmail 并将isLoggedIn 状态设置为false。您的应用程序永远不会到达this.state.isLoggedIn === true

以上是关于重新渲染 Reactjs 后,父组件立即失去状态的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS表单应用程序:如何阻止父组件重新渲染? /使用redux共享状态的正确方法

ReactJS:即使在重新渲染组件后复​​选框状态仍然存在

reactjs:动作后redux不会重新渲染

在 reactjs 组件中使用 fetch 重新初始化应用程序(状态)

在 ReactJS 中使用 state 和 Function 组件时如何使输入不失去焦点?

重新渲染 Reactjs 数组组件