反应原生建议 - 解决Redux Action OnPress Dispatch Action

时间:2018-03-24 19:43:16

标签: react-native redux react-redux redux-saga

我不熟悉在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));

减速机(如果有帮助)

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功能时,我注意到了什么,&#34; auth_token&#34;永远不会回来。但是,它在render()区域内返回。

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

1 个答案:

答案 0 :(得分:1)

我对redux-saga不太熟悉,但我会告诉你如果我的获取请求返回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不会更改。