首页 > 解决方案 > 在组件状态和带有 redux 的道具中使用相同的变量名,我得到未定义道具的错误

问题描述

我有组件需要知道用户是否使用Facebook登录,所以我使用该函数mapStateToPropsredux 状态映射到组件 props
同时,一些组件可以让用户自己登录,所以他们需要本地state知道用户是否登录(我无法更新组件本身内部的组件道具)。

当用户登录时,他们会发送一个loggedIn事件。

这是最佳实践还是我做错了什么?我有这样的组件:

import ...

const FBSDK = require('react-native-fbsdk');
const {
    LoginButton,
    AccessToken,
    LoginManager
} = FBSDK;

class Settings extends Component {

    constructor(props) {
        super(props);

        this.state = {
            isLoggedIn: false,
        };
    }

    componentDidMount () {
        this._loadInitialState();
    }

    async _loadInitialState() {
        AccessToken.getCurrentAccessToken().then(
            (data) => {
                if (data) {
                    this.setState({
                        isLoggedIn: true,
                    });

                    // Dispatch loggedIn action
                    this.props.loggedIn();
                }
            }
        );
    }

    render() {
        const {navigate} = this.props.navigation;

        return (
            <Content>
                <List style={styles.list}>
                    {this.state.isLoggedIn &&
                        <ListItem>
                            <Body>
                                ...
                            </Body>
                        </ListItem>
                    }
                    <ListItem style={styles.listItem}>
                        <LoginButton
                            readPermissions={["user_friends", "email"]}
                            onLoginFinished={
                                (error, result) => {
                                    if (error) {
                                        alert("login has error: " + result.error);
                                    } else if (result.isCancelled) {
                                        alert("login is cancelled.");
                                    } else {
                                        AccessToken.getCurrentAccessToken().then(
                                            (data) => {                                                                                                       this.setState({isLoggedIn: true});

                                                // Dispatch loggedIn action
                                                this.props.loggedIn();
                                            }
                                        ).catch(function(e) {
                                            log(e); // "oh, no!"
                                        });
                                    }
                                }
                            }
                            onLogoutFinished={() => {
                                this.setState({isLoggedIn: false});

                                // Dispatch loggedOut action
                                this.props.loggedOut();
                            }} />
                    </ListItem>
                </List>
            </Content>
        )
    }
}

Settings.propTypes = {
    isLoggedIn: PropTypes.bool.isRequired,
}

const mapStateToProps = (state) => {
    return {
        isLoggedIn: state.isLoggedIn,
    };
};

const mapDispatchToProps = (dispatch) => ({
    startup: () => dispatch(StartupActions.startup()),
    loggedIn: () => dispatch({
        type: LOGGED_IN
    }),
    loggedOut: () => dispatch({
        type: LOGGED_OUT
    })
});

export default connect(mapStateToProps, mapDispatchToProps, null, {pure: false})(Settings);

如您所见,该组件确实具有isLoggedIn本地状态和isLoggedIn道具,我需要同时更新两者。

我在问除了实践之外的原因,当我使用Facebook登录用户时,我收到了这个错误(我没有在哪里寻找,但似乎某处props未定义):

TypeError: Cannot read property 'loggedIn' of undefined

而且我不知道它发生在哪里以及为什么会发生以及它是否取决于此代码。

标签: javascriptreact-nativereact-reduxreact-props

解决方案


您需要绑定您的方法以访问this方法_loadInitialState

最简单的方法是使用箭头函数

 _loadInitialState = async() => {

完成更新后也会setState在其回调方法中调度操作

this.setState({
    isLoggedIn: true,
 }, () => this.props.loggedIn()); 

onLogoutFinished={() => {
   this.setState({isLoggedIn: false}, () => this.props.loggedOut());
}}

推荐阅读