【问题标题】:React Native / Redux - setState - Cannot update during an existing state transitionReact Native / Redux - setState - 在现有状态转换期间无法更新
【发布时间】:2017-01-05 01:17:02
【问题描述】:

我正在使用 React Native 和 Redux 构建应用程序,但在实施过程中遇到了问题。我收到一条错误消息,上面写着

setState 在现有状态转换期间无法更新(例如 在渲染或其他组件的构造函数中)。

当我加载应用模拟器时,它似乎会在任何用户输入之前立即(并且在循环中)触发 handleLogin()。

这是AuthenticationContainerAuthenticationPage 代码:

AuthenticationContainer.js:

'use strict'

import React, { Component, PropTypes } from 'react';
import AuthenticatePage from '../../components/Authenticate/AuthenticatePage'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import * as sessionActionCreators from '../../redux/session';
import {Actions, ActionConst} from 'react-native-router-flux'

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

    handleLogin() {
        this.props.doLogin(this.state.email, this.state.password)
            .then(() => Actions.tabbar())
    }

    render() {
        return (
            <AuthenticatePage
                doLogin = {this.handleLogin.bind(this)}
                error = {this.props.error}/>
        );
    }
}

AuthenticateContainer.propTypes = {
    doLogin: PropTypes.func.isRequired,
    email: PropTypes.string,
    password: PropTypes.string,
    error: PropTypes.string.isRequired
};

export default connect(
    (state) => ({isFetching: state.session.isFetching, error: state.session.error}),
    (dispatch) => bindActionCreators(sessionActionCreators, dispatch)
)(AuthenticateContainer)

AuthenticationPage.js

'use strict'

import React, { Component, PropTypes } from 'react';
import {Text, View, TouchableHighlight, AlertIOS} from 'react-native';
import t from 'tcomb-form-native'
import _ from 'lodash'
import EStyleSheet from 'react-native-extended-stylesheet'
import ViewContainer from '../ViewContainer'

// AuthenticatePage.propTypes = {
//     doLogin: PropTypes.func.isRequired,
//     onUpdateForm: PropTypes.func.isRequired,
//     email: PropTypes.string,
//     password: PropTypes.string,
//     error: PropTypes.string.isRequired
// };

var Form = t.form.Form;

var User = t.struct({email: t.String, password: t.String});

const options = {
    auto: 'placeholders',
    fields: {
        email: {
            autoCapitalize: 'none',
            autoCorrect: false
        },

        password: {
            autoCapitalize: 'none',
            autoCorrect: false,
            password: true,
            secureTextEntry: true
        }
    }
};

export default class AuthenticatePage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: {
                email: '',
                password: ''
            }
        };
    }

    render() {
        return (
            <ViewContainer>
                <View>
                    <Form
                        ref="form"
                        type={User}
                        options={options}
                        value={this.state.value}/>
                </View>
                <View>
                    <TouchableHighlight
                        onClick={this.props.doLogin()}
                        underlayColor='#99d9f4'>
                            <Text>{_.capitalize('Login')}</Text>
                    </TouchableHighlight>
                </View>
            </ViewContainer>
        )
    }
}

因此,handleLogin() 函数似乎会在页面加载时立即触发,并且会在抛出错误时重复运行。这是我从模拟器收到的错误。

任何帮助将不胜感激!

【问题讨论】:

  • 不得不问,你为什么在项目中同时使用 Redux 的同时直接改变状态?
  • 嗨 Maarten,您是指在 AuthenticationPage 中吗?我试图更改该组件的状态以处理来自表单的输入。这应该如何实现?
  • 使用本地状态来存储文本字段的值很好。但我不明白的是为什么你在两个组件中都有电子邮件和密码作为状态。您应该只在子组件中使用它,并且 doLogin 将 pass 和 email 作为函数调用中的参数。
  • 嗨,John,我假设子组件不应该将 props 作为参数传递给父组件。那是对的吗?这是我读到的地方:stackoverflow.com/questions/22639534/…

标签: javascript reactjs react-native redux


【解决方案1】:

我相信问题出在这里:

onClick={this.props.doLogin()}

您在render 上调用了一个函数,但您应该将它作为道具传递。要么尝试

onClick={() => this.props.doLogin()}

onClick={this.props.doLogin.bind(this)}

修复。

【讨论】:

    猜你喜欢
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 2017-05-16
    • 2016-09-20
    • 2017-09-04
    相关资源
    最近更新 更多