मेरे /actions/authenticate.jsमें कार्रवाई के तर्क को अलग करने के लिए redux और घटक में एक actionCreators है। मजबूत> प्रतिक्रिया की।

ये रहा मेरा authenticate.js जो मेरे एक्शन क्रिएटर है

export function login(email, password) { // Fake authentication function
    return async dispatch => {
        dispatch(loginRequest()); // dispatch a login request to update the state
        try {
            if (email.trim() === "test123@nomail.com" && password === "123456") { //If the email and password matches
                const session = { token: "abc1234", email: email, username: "test123" } // Create a fake token for authentication
                await AsyncStorage.setItem(DATA_SESSION, JSON.stringify(session)) // Stringinfy the session data and store it
                setTimeout(() => { // Add a delay for faking a asynchronous request
                    dispatch(loginSuccess(session)) // Dispatch a successful sign in after 1.5 seconds
                    return Promise.resolve()
                }, 1500)
            } else { // Otherwise display an error to the user
                setTimeout(() => { // Dispatch an error state
                    dispatch(loginFailed("Incorrect email or password"))
                }, 1500)
            }
        } catch (err) { // When something goes wrong
            console.log(err)
            dispatch(loginFailed("Something went wrong"));
            return Promise.reject()
        }
    };
} // login

फिर मैं उस actionCreator को आयात करने के लिए अपने someComponent.js में आयात करता हूं और बाइंडएक्शनक्रिएटर्स.

कुछ इस तरह नीचे:

import { bindActionCreators } from "redux";
import * as authActions from "../actions/authenticate";
import { connect } from "react-redux";

फिर मैं उस क्रिया को अपने घटक से जोड़ता हूं जो कि Login.js है

export default connect(
    state => ({ state: state.authenticate }),
    dispatch => ({
        actions: bindActionCreators(authActions, dispatch)
    })
)(Login);

तो मैं उस क्रिया निर्माता में सीधे Login.js में फ़ंक्शन का आह्वान कर सकता हूं

कुछ इस तरह नीचे:

onPress={() => {                                 
   this.props.actions.login(this.state.email, this.state.password)
}}

लेकिन मैं क्या करना चाहता हूं कि यह फ़ंक्शन प्रेषण एक redux क्रिया करेगा और यदि संभव हो तो एक वादा भी लौटाएगा?

कुछ इस तरह:

onPress={() => {                                 
       this.props.actions.login(this.state.email, this.state.password)
       .then(() => this.props.navigation.navigate('AuthScreen'))
    }}

जब मैं साइन इन करने का प्रयास करता हूं तो मैं क्या करना चाहता हूं। उन एसिंक्रोनस रेडक्स थंक क्रियाओं को डिस्पैच करें और साथ ही एक वादा वापस करें। अगर हल हो गया है या नहीं तो मैं सही स्क्रीन पर रीडायरेक्ट या नेविगेट कर सकता हूं।

सराहना करें अगर कोई मदद कर सकता है। अग्रिम में धन्यवाद।

3
KnowledgeSeeker 13 फरवरी 2019, 03:39

2 जवाब

सबसे बढ़िया उत्तर

आपका पहला दृष्टिकोण ज्यादातर सही था। dispatch(thunkAction()) (या आपके मामले में this.props.actions.login() thunkAction() जो कुछ भी लौटाता है, उसे लौटाता है, इसलिए अगर यह async है तो यह करता है वादा करता है।

समस्या यह है कि वह वादा क्या हल करता है, जो कि आप async फ़ंक्शन से वापस आते हैं। आपके मामले में, आप setTimeout की प्रतीक्षा नहीं करते हैं और केवल void लौटाते हैं, भले ही क्रेडेंशियल सही थे या नहीं।

तो, async फ़ंक्शंस के संदर्भ में आपको कुछ इस तरह की आवश्यकता होगी

export function login(email, password) { // Fake authentication function
    return async dispatch => {
        dispatch(loginRequest()); // dispatch a login request to update the state
        try {
            if (email.trim() === "test123@nomail.com" && password === "123456") { //If the email and password matches
                const session = { token: "abc1234", email: email, username: "test123" } // Create a fake token for authentication
                await AsyncStorage.setItem(DATA_SESSION, JSON.stringify(session)) // Stringinfy the session data and store it
                // Add a delay for faking a asynchronous
                await new Promise((resolve, reject) => setTimeout(() => resolve(), 1500));
                dispatch(loginSuccess(session));
                return Promise.resolve(true);
            } else { // Otherwise display an error to the user
                await new Promise((resolve, reject) => setTimeout(() => resolve(), 1500));
                dispatch(loginFailed("Incorrect email or password"))
                return Promise.resolve(false);
            }
        } catch (err) { // When something goes wrong
            console.log(err)
            dispatch(loginFailed("Something went wrong"));
            return Promise.reject()
        }
    };
} // login

इस तरह, आपका async फ़ंक्शन true/false का समाधान करता है जिसे आप अपने घटक में उपयोग कर सकते हैं:

onPress={() => {                                 
       this.props.actions.login(this.state.email, this.state.password)
       .then((login_succeeded) => this.props.navigation.navigate('AuthScreen'))
    }}

आप return dispatch(loginSuccess(session)); भी कर सकते हैं (जब तक कि यह थंक है जो इसे लौटाता है, न कि setTimeout हैंडलर), उस स्थिति में loginSuccess(session) वही है जो .then() आपके onPress हुक।

6
Maciek Wawro 14 फरवरी 2019, 03:53

यदि आपको login परिणाम के आधार पर उपयोगकर्ता को किसी अन्य पृष्ठ पर पुनर्निर्देशित करने की आवश्यकता है, तो आपको का उपयोग करना चाहिए Redux राउटर, फिर अपने login थंक में आपको एक उपयुक्त नेविगेशन क्रिया जो आपके उपयोगकर्ता को सही पृष्ठ पर पुनर्निर्देशित करेगी।

0
bnopne 13 फरवरी 2019, 13:55