调用操作后未更新 React 原生 redux 道具 [英] React native redux props not updated after calling an action

查看:37
本文介绍了调用操作后未更新 React 原生 redux 道具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 React、React Native 和 Redux 的新手,我有一个 React Native 应用程序,该应用程序在渲染中具有此登录

I'm new to react, react native, and redux, I have a react native app that has this login in render

    render() {
       return (<TouchableOpacity style={Style.btnSubmit} onPress={this.onLoginPressed.bind(this)}>
                <Text style={Style.btnText}>Login</Text>
              </TouchableOpacity>)
}

和 onLoginPressed 函数在这里

and the onLoginPressed function is here

onLoginPressed() {
        const { username, password } = this.props.form;
        this.props.login({ username, password}); // the login is using the fetch api

        // props are not updated with the new state values
        console.log(this.props)
    }

一切正常,但道具不会在 onLoginPressed 函数中更新,但是,当我在渲染函数中控制台记录道具时,它会更新.我知道 redux 做了一个完整的渲染,但我真的不明白它是否应该在调用登录后更新 props.

Everything is working correctly but the props doesn't update in the onLoginPressed function, however, when I console log the props inside the render function, it's updated. I understand that redux do a full rendering, but I just don't really understand if it should update the props after calling the login.

谢谢

更新这里是组件的结尾

function mapStateToProps(state) {
    return {
        ...state.login
    }
}

function mapDispatchToProps(dispatch) {
    return {
        login: (formData) => dispatch(login(formData)),
        facebookLogin: (formData) => dispatch(facebookLogin(formData)),
        setUsername: (username) => dispatch(setUsername(username)),
        setPassword: (password) => dispatch(setPassword(password)),        
    }
}


export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Login);

这里是操作

import { Host, Endpoints } from '../config/server';
import { loginActions } from '../config/constants';


/*
    * state props
        - form
        - inProgress
        - error
        - data
*/

export function login(form) {
    return (dispatch) => {
        dispatch(loggingIn(true));
        fetch(Host + Endpoints.auth.login, {
            method: 'POST',
            headers: {
                'content-type': 'application/json'
            },
            body: JSON.stringify(form)
        })
            .then(res => res.json())
            .then(res => { 
                dispatch(loggingIn(false));                
                res.error ? dispatch(loginError(res.error)) : 
                            dispatch(loginSuccess(res.data));
            })
            .catch(err => dispatch(loginError(err)));
    }
}

export function facebookLogin(data) {
    return (dispatch) => {
        dispatch(loggingIn());

        fetch(Host + Endpoints.auth.facebookLogin, {
            method: 'POST',
            headers: {
                'content-type': 'application/json'
            },
            body: JSON.stringify(data)
        })
        .then(res => res.json())
        .then(data => dispatch(loginSuccess(data)))
        .catch(err => dispatch(loginError(err)));
    }
}

export function setUsername(username) {
    return {
        type: loginActions.setUsername,
        username
    }
}

export function setPassword(password) {
    return {
        type: loginActions.setPassword,
        password
    }
}

function loginSuccess(data) {
    return {
        type: loginActions.LoginSuccess,
        data
    }
}

function loginError(error) {
    return {
        type: loginActions.LoginError,
        error
    }
}

function loggingIn(val) {
    return {
        type: loginActions.LoggingIn,
        inProgress: val
    }
}

这里是减速器

import { loginActions } from '../config/constants';

const initialState = {
  form: {
    username: '',
    password: ''
  },
  data: null,
  inProgress: false,
  error: null
};

export default function loginReducer(state = initialState, action) {
    switch(action.type) {
        case loginActions.LoggingIn: 
            return {
                ...state,
                inProgress: action.inProgress
            }            
        case loginActions.LoginError:
             return {
                ...state, 
                error: action.error,
            }

        case loginActions.LoginSuccess:
            return {
                ...state,
                inProgress: false,
                error: null,
                data: action.data
            }
        case loginActions.setUsername:
            return {
                ...state,
                form: { 
                    username: action.username,
                    password: state.form.password
                }
            }
        case loginActions.setPassword:
            return {
                ...state,
                form: { 
                    username: state.form.username,
                    password: action.password
                }
            }
        default: 
            return {
                ...state
            }
    }
}

和reducer索引文件

and the reducer index file

import { combineReducers } from 'redux';
import login from './login';

const rootReducer = combineReducers({
    login
});

export default rootReducer;

和 configureStore 文件

and the configureStore file

import { createStore, applyMiddleware } from 'redux'
import reducers from './reducers'
import thunk from 'redux-thunk'

export default function configureStore() {
  let store = createStore(reducers, applyMiddleware(thunk))
  return store
}

当然,根由传递商店的提供者包装.

of course the root is wrapped with the provider passing the store.

推荐答案

您在调度登录操作的同一个函数调用中执行 console.log.这是行不通的,因为 JavaScript 是非阻塞的,它不会在调用 console.log 之前等待登录操作完成并更新 props

You are doing console.log in the same function call that dispatch the login actions. That won’t work, because JavaScript is non-blocking, it will not wait for the login action to complete and update the props before calling console.log

在 componentWillReceiveProps 之类的东西中尝试 console.log.

Try console.log in something like componentWillReceiveProps.

这篇关于调用操作后未更新 React 原生 redux 道具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆