Я не понимаю, откуда пришло моё предупреждение React «не могу вызвать setstate на не смонтированном компоненте» - PullRequest
0 голосов
/ 14 января 2019

Итак, у меня есть следующий код:

<UserConsumer>
{({ actions }) => {
    return (
        <span onClick={() => this.requestAuth(actions)}><MainButton name='Log in' /></span>
    )
}}
</UserConsumer>

Где this.requestAuth сначала отправляет запрос на публикацию и - после успешной обратной связи - устанавливает состояние «true», используя событие моих действий для моего потребителя. Тем не менее, я обнаружил - после опыта - что я всегда получаю следующую ошибку после переноса моего в :

Предупреждение. Невозможно вызвать setState (или forceUpdate) для неустановленного компонента. Это не работает, но это указывает на утечку памяти в вашем приложении. Чтобы исправить, отмените все подписки и асинхронные задачи в методе componentWillUnmount. в логине (в App.js: 207).

Однако я не понимаю, почему это происходит.

Это мой полный код Login.js:

export default class Login extends Component  {

    constructor (props) {
        super (props)
        this.state = {
            pwVisible : false,
            pwUser: '',
            mailUser: '',
            feedback: null
        }
    }

    requestAuth = (actions) => {
        axios({
            method: 'post',
            url: process.env.REACT_APP_API_AUTH,
            data: {
                username: this.state.mailUser,
                password: this.state.pwUser
            }
        })
        .then(
            (response) => {
                console.log(response)
                this.setState({
                    feedback: "Alright, welcome back! I'm gonna log you in!"
                }, actions.logIn())
            }
        )
        .catch(
            (error) => {
                console.log(error)
                this.setState({
                    feedback: "Sorry, I think your e-mail or password is incorrect. Wanna try again?"
                })
            }
        );

    }
    render () {
        return (
            <div id='login'>
                <div id='loginBox'>
                    {Logo}
                    <form>
                        <input className='input100' value={this.state.mailUser} onChange={thisValue => this.setState({mailUser : thisValue.target.value}) } type='email' name='user' placeholder='firstname.lastname@ondernemersnetwerk.be' />
                        <input className='input100' value={this.state.pwUser} onChange={thisValue => this.setState({pwUser : thisValue.target.value}) } type={this.state.pwVisible? 'text' : 'password'} name='password' placeholder='Password' required />
                        <span className='pwIcon' onClick={this.state.pwVisible ? () => this.setState({pwVisible : false}) : () => this.setState({pwVisible : true})}>
                        {this.state.pwVisible ?
                            <Icon name='Visible' />
                        :
                            <Icon name='Hidden' />
                        }
                        </span>
                        <UserConsumer>
                            {({ actions }) => {
                                return (
                                    <span onClick={() => this.requestAuth(actions)}><MainButton name='Log in' /></span>
                                )
                            }}
                        </UserConsumer>
                    </form> 

                    <div className='gradientBorder'></div>
                </div>
            </div>
        );
    }
};

1 Ответ

0 голосов
/ 14 января 2019

Это предупреждение, потому что вы вызываете setState после размонтирования компонента. Попробуйте установить флаг _isMounted и проверить перед звонком setState:

export default class Login extends Component  {
    _isMounted = false;
    constructor (props) {
        super (props)
        this.state = {
            pwVisible : false,
            pwUser: '',
            mailUser: '',
            feedback: null
        }
    }

    componentDidMount() {
        this._isMounted = true;
    }

    componentWillUnmount() {
        this._isMounted = false;
    }

    requestAuth = (actions) => {
        axios({
            method: 'post',
            url: process.env.REACT_APP_API_AUTH,
            data: {
                username: this.state.mailUser,
                password: this.state.pwUser
            }
        })
        .then(
            (response) => {
                console.log(response)
                if (this._isMounted) {
                    this.setState({
                        feedback: "Alright, welcome back! I'm gonna log you in!"
                    }, actions.logIn())
                }
            }
        )
        .catch(
            (error) => {
                console.log(error)
                if (this._isMounted) {
                    this.setState({
                        feedback: "Sorry, I think your e-mail or password is incorrect. Wanna try again?"
                    })
                }
            }
        );

    }
    render () {
        return (
            <div id='login'>
                <div id='loginBox'>
                    {Logo}
                    <form>
                        <input className='input100' value={this.state.mailUser} onChange={thisValue => this.setState({mailUser : thisValue.target.value}) } type='email' name='user' placeholder='firstname.lastname@ondernemersnetwerk.be' />
                        <input className='input100' value={this.state.pwUser} onChange={thisValue => this.setState({pwUser : thisValue.target.value}) } type={this.state.pwVisible? 'text' : 'password'} name='password' placeholder='Password' required />
                        <span className='pwIcon' onClick={this.state.pwVisible ? () => this.setState({pwVisible : false}) : () => this.setState({pwVisible : true})}>
                        {this.state.pwVisible ?
                            <Icon name='Visible' />
                        :
                            <Icon name='Hidden' />
                        }
                        </span>
                        <UserConsumer>
                            {({ actions }) => {
                                return (
                                    <span onClick={() => this.requestAuth(actions)}><MainButton name='Log in' /></span>
                                )
                            }}
                        </UserConsumer>
                    </form> 

                    <div className='gradientBorder'></div>
                </div>
            </div>
        );
    }
};

Надеюсь, это поможет.

...