代码之家  ›  专栏  ›  技术社区  ›  SurinderBhomra

React Native Advice-在Press Dispatch Action上启动Redux操作

  •  0
  • SurinderBhomra  · 技术社区  · 7 年前

    我不熟悉在React本机应用程序中使用Redux。当用户按下应用程序中的按钮时,我需要一些关于如何启动redux操作的建议。

    我有一个登录屏幕,用户可以在其中输入用户名和密码,然后 fetchData 按下按钮时的重复操作。这个 获取数据 操作使用Redux Saga发出API请求以使用户有效,如果有效,将返回“auth\u令牌”。

    我想实现的是,如果返回身份验证令牌,则用户将被重定向到我的 onPress 作用

    这是我目前的代码。。。

    登录屏幕

    import PropTypes from 'prop-types';
    import React, { Component} from 'react';
    import { Container } from '../components/Container';
    import { StatusBar, Text, TextInput, Button } from 'react-native';
    import { setItem } from '../storage/sensitive'
    import { connectAlert } from "../components/Alert";
    import { connect } from "react-redux";
    import { fetchData } from "../redux/actions/userLogin";
    
    class SignIn extends Component {
        static propTypes = {
            navigation: PropTypes.object,
            dispatch: PropTypes.func,
            authToken: PropTypes.string,
            //appData: PropTypes.object
        };
    
        state = {
            username: '',
            password: '',
            error: '',
            appData: {}
        }
    
        componentWillMount() {
    
        }
    
        onPressSignIn = () => {
            // Check if the username and password fields are entered.
            if (this.state.username === '' || this.state.password === '') {
                this.setState({error: 'Please ensure you have entered a username and password '});
            }
            else {
                // Remove error message if one was rendered previously.
                this.setState({error: ''})
    
                // Send user credentials to loginUser function to retrieve Authentication Token.
                this.props.dispatch(fetchData(this.state.username, this.state.password));
    
                // HOW?: Output 'this.props.appData.data.user.auth_token' to determine whether the user is valid
                //        If valid redirect to another screen.
            }
    
        };
    
        render() {
             let test = this.props.appData;
             console.log('Get Auth Token', test.data.user ? test.data.user.auth_token : 'no token');
            return (
                <Container>
                    <StatusBar barStyle="default" />
                    <Text>Sign In</Text>
                    <TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}
                               placeholder="Username"
                               value={this.state.username}
                               email-address={true}
                               onChangeText={username => this.setState({username})} />
                    <TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}
                               placeholder="Password"
                               value={this.state.password}
                               onChangeText={password => this.setState({password})}
                               secureTextEntry={true} />
                    <Button onPress={this.onPressSignIn} title="Sign In" color="#841584" accessibilityLabel="Sign in to your account" />
                    {this.state.error &&
                        <TextInput value={this.state.error} />
                    }
                    {this.state.appData.isFetching && <TextInput value='Loading' />}
                </Container>
            );
        }
    }
    
    const mapStateToProps = (state) =>  {
        console.log('mapStateToProps', state);
        return {
            appData: state.userLoginReducer
        }
    }
    
    export default connect(mapStateToProps)(connectAlert(SignIn));
    

    减速器(如果有帮助)

    import { FETCHING_DATA, FETCHING_DATA_SUCCESS, FETCHING_DATA_FAILURE } from '../actions/userLogin'
    
    const initialState = {
        data: [],
        username: '',
        password: '',
        dataFetched: false,
        isFetching: false,
        error: false
    }
    
    const userLoginReducer = (state = initialState, action) => {
        switch (action.type) {
            case FETCHING_DATA:
                return {
                    ...state,
                    data: [],
                    isFetching: true,
                    username: action.username,
                    password: action.password
                }
            case FETCHING_DATA_SUCCESS:
                return {
                    ...state,
                    isFetching: false,
                    data: action.result
                }
            case FETCHING_DATA_FAILURE:
                return {
                    ...state,
                    isFetching: false,
                    error: true
                }
            default:
                return state
        }
    }
    
    export default userLoginReducer;
    

    用户按下时我注意到的内容 onPressSignIn 函数,则不会返回“auth\u令牌”。但是,它会在render()区域内返回。

    我是否需要进行检查以确定此时用户是否成功登录?只有在这里,我才能从我的Redux操作类型中获得成功响应。

    1 回复  |  直到 7 年前
        1
  •  1
  •   G4bri3l    7 年前

    我不太熟悉 redux-saga 但我会告诉你,如果我的取回请求返回了承诺,或者没有,我会怎么做 Promise 它看起来像这样(请记住,我通常使用 bindActionCreators 将调度映射到道具的方法):

     onPressSignIn = () => {
       if (this.state.username === '' || this.state.password === '') {
         this.setState({error: 'Please ensure you have entered a username and password '});
       } else {
         this.setState({error: ''})
    
         fetchData(this.state.username, this.state.password)
           .then(res => {
             // Here you can have all kinds of logic to decide if
             // redirect should occur or not
             if (res.isUserAuthenticated) redirectTo('/anotherScreen');
           });
     };
    

    否则我只会使用 componentDidUpdate :

    componentDidUpdate() {
      // At this point your props are up to date as this lifecycle method
      // is called every time your component receives new props
      const test = this.props.appData;
      if (test.data.user.auth_token) redirectTo('/anotherScreen');
    }
    

    在这种情况下 onPressSignIn 不会改变。