React Native Advice - 触发 Redux Action OnPress Dispatch Action

React Native Advice - Firing Redux Action OnPress Dispatch Action

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

我有一个登录屏幕,用户可以在其中输入用户名和密码,按下按钮时会触发 fetchData Redux 操作。 fetchData 操作使用 Redux Saga 发出 API 请求来验证用户,如果有效,将返回 "auth_token"。

我想要实现的是,如果返回身份验证令牌,用户将被重定向到我的 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));

Reducer(如果有帮助的话)

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_token" 永远不会返回。但是,它在 render() 区域内返回。

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

我对 redux-saga 不是很熟悉,但我会告诉您如果我的获取请求返回 Promise 或没有返回 Promise,我会怎么做。如果您的获取请求返回 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 不会改变。