【问题标题】:React-native not rerendering with Redux actionReact-native 不使用 Redux 操作重新渲染
【发布时间】:2019-07-19 07:56:26
【问题描述】:

我有一个在用户通过身份验证时应该导航的组件:

componentDidUpdate(prevProps, prevState) {
    if (this.props.authenticated) {
      this.props.navigation.navigate('Main')
    }
  }

当我发送 authLogin 时,它应该会导致重新渲染,它会处理导航:

export const authLogin = (username, password) => {
  return dispatch => {
    dispatch(authStart());
    axios.post(`http://10.0.2.2:8000/api/v1/rest-auth/login/`, {
      username: username,
      password: password
    })
      .then(response => {
        var token = response.data.key;
        try {
          AsyncStorage.setItem('token', token);
        } catch (err) {
          console.log(err)
        }
        dispatch(authSuccess(token));
      })
      .catch(err => {
        dispatch(authFail());
        console.log(err);
      })
  }
}

这是我的减速器:

export default function (state = initialState, action) {
  switch (action.type) {
    case "AUTH_START": {
      return {
        ...state,
        authenticating: true,
      }
    }
    case "AUTH_SUCCESS": {
      return {
        ...state,
        authenticating: false,
        authenticated: true,
        token: action.token,
      }
    }
    case "AUTH_FAIL": {
      return {
        ...state,
        authenticating: false,
        authenticated: false,
      }
    }
    case "AUTH_LOGOUT": {
      return {
        ...state,
        authenticating: false,
        authenticated: false,
        token: null,
      }
    }
    default:
      return state
  }
}

和动作创建者:

export const authStart = () => ({type: "AUTH_START"})
export const authSuccess = token => ({type: "AUTH_SUCCESS", token})
export const authFail = () => ({type: "AUTH_FAIL"})

我的控制台正在记录 Redux 操作已分派并且状态正在更改,但没有发生重新渲染。这是整个组件:

import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import LoginForm from '../components/LoginForm';
import { authLogin } from '../actions/authActions';

export class LoginScreen extends Component {
  handlePress = async (username, password) => {
    await this.props.authLogin(username, password);
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props.authenticated) {
      this.props.navigation.navigate('Main')
    }
  }

  render() {
    return (
      <View style={styles.loginForm}>
        <LoginForm handlePress={this.handlePress} {...this.props} />
      </View>
    );
  }
}

const mapState = state => {
  return {
    authenticated: state.auth.authenticated
  }
};

const mapDispatch = dispatch => {
  return bindActionCreators({
    authLogin,
  }, dispatch)
};

export default connect(mapState, mapDispatch)(LoginScreen);

LoginScreen.propTypes = {
  authLogin: PropTypes.func.isRequired,
  authenticated: PropTypes.bool.isRequired,
};

const styles = StyleSheet.create({
  loginForm: {
    justifyContent: 'center',
    alignItems: 'center',
    flex: 1
  }
});

这是我的商店:

import {  combineReducers } from 'redux';
import { createStore, applyMiddleware } from 'redux';
import { logger } from 'redux-logger';
import thunk from 'redux-thunk';
import auth from './auth'

const reducer = combineReducers({auth})
const enhancer = applyMiddleware(thunk, logger)
const store = createStore(reducer, enhancer)

export default store

商店在App.js中的Provider中连接。

【问题讨论】:

  • 关于 componentDidUpdate 的一个怪癖是它在初始渲染时没有被调用,如果你在其中 console.log 它会被记录吗?
  • @Dmitriy console.log 没有被调用。我不担心初始渲染,因为我使用的是这样的身份验证导航:reactnavigation.org/docs/en/auth-flow.html
  • 不带 IF 条件试试看,componentWillUpdate 执行导航时是否有效!
  • @Arvindh componentWillUpdate 永远不会被触发

标签: reactjs react-native redux react-redux


【解决方案1】:

为什么不将身份验证检查和导航语句放在 handlePress() 中。

handlePress = async (username, password) => {
    await this.props.authLogin(username, password);
    if (this.props.authenticated) {
      this.props.navigation.navigate('Main')
    }
  }

authLogin() 派发动作并更新状态后,您可以检查身份验证状态并导航用户。

希望这会有所帮助!

【讨论】:

  • 不走运。我在等待之后和 if 之前放置了一个 console.log 语句。 Navigate 在发送 AUTH_START 之后但在发送 AUTH_SUCCESS 或 AUTH_FAIL 之前被调用,这会改变 this.props.authenticated
  • @peter176 尝试将您的代码放入 componentDidMount() 而不是 componentDidUpdate()。
  • 我不希望它在首次挂载时导航,而是在更新和 this.props.authenticated === true 时导航
【解决方案2】:

我添加了另一个减速器,它立即修复了它。显然 redux 不喜欢 combineReducers() 只有一个参数。

即改变

const reducer = combineReducers({auth})

到

const reducer = combineReducers({auth, otherReducer})

【讨论】:

  • 刚刚遇到这个问题,不知道为什么没有将其标记为错误
猜你喜欢
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 2019-09-26
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多