【问题标题】:setState not resetting state / switching between modalssetState 不重置状态/在模态之间切换
【发布时间】:2020-08-09 13:49:53
【问题描述】:

我之前问过类似的问题,但没有得到太多回复。我有两种用户身份验证模式:加入和登录。每个模态都有一个到另一个的链接。当您单击“注册”并切换到加入模式时,显示的登录错误仍然存​​在,反之亦然。我试图将 state.errors 设置为空数组,但错误仍然存​​在。我将handleSwitch 更改为回调。错误数组仍然有长度。我尝试使用switched作为状态的一部分,在handleSwitch和三元中将其重置为true,也没有结果。任何人都可以提出替代解决方案。

import React from 'react';

class Login extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: '',
            errors: [],
            switched: false
        };
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleSwitch = this.handleSwitch.bind(this);
        this.mapErrors = this.mapErrors.bind(this);
        this.handleErrors = this.handleErrors.bind(this);
    }

    componentDidMount() {
        this.setState({ errors: this.props.errors})
    }

    componentDidUpdate(prev) {
        if (prev.errors.length !== this.props.errors.length) {
            this.setState( {errors: this.props.errors} )
        }
    }

    handleInput(type) {
        return (err) => {
            this.setState({ [type]: err.currentTarget.value })
        };
    }

    handleSubmit(event) {

        event.preventDefault();
        const user = Object.assign({}, this.state);
        this.props.processForm(user)
            // .then(() => this.props.history.push('/users')); //change to /videos later
    }

    handleSwitch() {
        // debugger
        this.setState({ errors: [] }, function () {
            this.props.openModal('signup')
        });
        // debugger
    }

    mapErrors() {
        if (this.state.errors.length) {
            return this.state.errors.map((error, i) => {
                return <p key={i}>{error}</p>
            })
        }
    }

    handleErrors() {
        debugger
        if (!this.state.switched) {
            return <div className="errors">{this.mapErrors}</div>
        } else {
            return null;
        }
    };


    render() {
        console.log(this.state.errors)
        return (
            <div className="login-form">
                <div>
                    <h2 className="login-header">Log in to Foxeo</h2>
                </div>
                <form>
                    <input className="login-email"
                        type="text"
                        value={this.state.email}
                        placeholder="Email address"
                        onChange={this.handleInput('email')}
                    />
                    <input className="login-password"
                        type="password"
                        value={this.state.password}
                        placeholder="Password"
                        onChange={this.handleInput('password')}
                    />
                    
                    <div className="errors">{this.mapErrors()}</div>
                
                
                    {/* { this.state.switched ? 
                        <div className="errors">{this.handleErrors()}</div> :
                        <div className="errors">{this.mapErrors()}</div>
                    } */}
            
                    
                    <button className="login-button" onClick={this.handleSubmit}>Log in with email</button>

                    <div className="login-footer">Don't have an account?
                        {/* <button className="login-form-btn" onClick={() => this.props.openModal('signup')}>Join</button> */}
                        <button className="login-form-btn" onClick={ this.handleSwitch}> Join</button>
                    </div>
                </form>
            </div>
        );
    }
};

export default Login;

【问题讨论】:

  • 请提供codesandbox
  • Codebox 不工作,错误来自 ruby​​ 后端并且 openModal 在不同的组件中
  • errors 上的props - 有没有可能发生变化?
  • 它们持久且只读,因此我试图改变状态
  • @user13790968 为什么要将 redux 存储值复制到本地状态,而不是仅使用 redux 存储(props)中的值?您没有重置 redux 存储中的错误,因此错误继续作为道具传递。

标签: javascript html reactjs forms react-redux


【解决方案1】:

我建议从道具而不是状态中获取新错误:

    mapErrors() {
        if (this.props.errors.length) {
            return this.props.errors.map((error, i) => {
                return <p key={i}>{error}</p>
            })
       

【讨论】:

    【解决方案2】:

    调度 resetErrors 操作解决了该问题。 handleSwitch 方法很简单:

        handleSwitch() {
            this.props.resetErrors()
            this.props.openModal('signup')
        }
    

    会话操作:

    import * as apiUtil from '../util/session_api_util';
    
    export const RECEIVE_CURRENT_USER = 'RECEIVE_CURRENT_USER';
    export const LOGOUT_CURRENT_USER = 'LOGOUT_CURRENT_USER';
    export const RECEIVE_ERRORS = 'RECEIVE_ERRORS';
    export const CLEAR_ERRORS = 'CLEAR_ERRORS';
    
    const receiveErrors = (errors) => ({
        type: RECEIVE_ERRORS,
        errors
    })
    
    const clearErrors = () => ({
        type: CLEAR_ERRORS,
        errors: []
    })
    
    const receiveCurrentUser = (user) => ({
        type: RECEIVE_CURRENT_USER,
        user
    });
    
    const logoutCurrentUser = () => ({
        type: LOGOUT_CURRENT_USER
    });
    
    
    export const signup = user => dispatch => (
        apiUtil.signup(user).then(user => (
            dispatch(receiveCurrentUser(user))
        ), err => (
            dispatch(receiveErrors(err.responseJSON))
        ))
    );
    
    export const login = user => dispatch => {
        return apiUtil.login(user).then(user => {
            dispatch(receiveCurrentUser(user))
        }, err => (
            dispatch(receiveErrors(err.responseJSON))
        ))
    };
    
    export const logout = () => dispatch => apiUtil.logout()
        .then(() => dispatch(logoutCurrentUser())); 
    
    export const resetErrors = () => dispatch(clearErrors());
    

    会话错误减少器:

    import { RECEIVE_ERRORS, RECEIVE_CURRENT_USER, CLEAR_ERRORS } from '../actions/session_actions';
    
    
    const sessionErrorsReducer = (state = [], action) => { 
    
        Object.freeze(state);
        switch (action.type) {
            case RECEIVE_ERRORS:
                return action.errors; 
            case CLEAR_ERRORS:
                return [];
            case RECEIVE_CURRENT_USER:
                return []; 
            default:
                return state;
        }
    };
    
    export default sessionErrorsReducer;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-09
      相关资源
      最近更新 更多