反应本机排空道具

时间:2018-10-19 21:22:16

标签: react-native react-redux reducers react-props

我有一个包含“登录”和“注册”按钮的屏幕。当用户点击SigninButton时,我将其发送到登录屏幕。在登录屏幕中,有两个文本输入,用于接收来自用户的电子邮件和密码。如果成功,则将用户发送到主屏幕。如果没有,我抛出一个错误文本。但是,如果用户从导航栏返回并返回登录屏幕,则电子邮件输入和错误消息仍显示在此处。我正在使用redux,无法清空保存电子邮件和错误文本的道具。我尝试了componentWillUnmount,componentWillMount等,但仍然找不到清空这些道具的正确位置。这是我的登录屏幕中的代码;

class LoginScreen extends Component {

  componentWillReceiveProps(nextProps) {
    this.onAuthComplete(nextProps);
  }

  onAuthComplete(props) {
    if (props.user) {
      this.props.navigation.navigate('main');
    }
  }

  render() {
    return(
      <View style={styles.container}>
        <SigninForm />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  ........
  }
});

const mapStateToProps = ({ auth }) => {
  const { user, email, error } = auth;

  return { user, email, error };
}

export default connect(mapStateToProps, { emailChanged, loginUser })(LoginScreen);

这也是化简器中的代码;

import ......

const INITIAL_STATE = {
  email: '',
  password: '',
  user: null,
  error: '',
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case EMAIL_CHANGED:
      return {...state, email: action.payload };
    case PASSWORD_CHANGED:
      return {...state, password: action.payload };
    case LOGIN_USER:
      return {...state, error: ''};
    case LOGIN_USER_SUCCESS:
      return {...state, ...INITIAL_STATE, user: action.payload};
    case LOGIN_USER_FAIL:
      return {...state, error: 'Authentication Failed', password: ''};
    default:
      return state;
  }
};

这是SigninForm代码;

import React, { Component } from 'react';
import { View, Dimensions, Text } from 'react-native';
import { connect } from 'react-redux';
import { FormInput, FormLabel } from 'react-native-elements';
import { AuthButton } from './';
import { emailChanged, passwordChanged, loginUser } from '../actions';

const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;

class SigninForm extends Component {

  onEmailChange(text) {
    this.props.emailChanged(text);
  }

  onPasswordChange(text) {
    this.props.passwordChanged(text);
  }

  onButtonPress() {
      const { email, password } = this.props;
      this.props.loginUser({ email, password });
  }

  render() {
    return(
      <View style={styles.viewStyle}>
        <FormLabel labelStyle={styles.labelStyle}>Email</FormLabel>
        <FormInput
          placeholder='Enter your email'
          keyboardType="email-address"
          containerStyle={styles.containerStyle}
          inputStyle={styles.inputStyle}
          onChangeText={this.onEmailChange.bind(this)}
          value={this.props.email}
        />
        <FormLabel labelStyle={styles.labelStyle}>Password</FormLabel>
        <FormInput
          placeholder='Enter a password'
          secureTextEntry={true}
          containerStyle={styles.containerStyle}
          inputStyle={styles.inputStyle}
          onChangeText={this.onPasswordChange.bind(this)}
          value={this.props.password}
        />
        <Text style={styles.errorTextStyle}>
          {this.props.error}
        </Text>
        <AuthButton
          title='Sign In'
          backgroundColor='#eb4454'
          onPress={this.onButtonPress.bind(this)}
        />
      </View>
    );
  }
}
const styles = {
  viewStyle: {
    top: SCREEN_HEIGHT * -0.15
  },
  containerStyle: {
    marginBottom: 10,
    width: SCREEN_WIDTH * 0.80,
    borderBottomColor: '#3c143c'
  },
  labelStyle: {
    color: '#3c143c',
    fontFamily: 'System',
    fontSize: 20
  },
  inputStyle: {
    color: '#3c143c',
    fontFamily: 'System',
    fontSize: 20
  },
  errorTextStyle: {
    fontSize: 20,
    alignSelf: 'center',
    color: 'red'
  }
}

const mapStateToProps = ({ auth }) => {
    const { email, password, error } = auth;

    return { email, password, error };
}

export default connect(mapStateToProps, { emailChanged, passwordChanged, loginUser })(SigninForm);

1 个答案:

答案 0 :(得分:0)

我在componentWillMount方法中做到了。我调用了一个动作来触发化简器更新相关道具的状态。这是我组件中的代码片段;

import React, { Component } from 'react';
import { View, Dimensions, Text } from 'react-native';
import { connect } from 'react-redux';
import { FormInput, FormLabel } from 'react-native-elements';
import { AuthButton } from './';
import { emailChanged, passwordChanged, loginUser, emptyInput } from '../actions';

const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;

class SigninForm extends Component {
  componentWillMount() {
    //used for empty email and error text when user go back and forth
    const { email, error } = this.props;
    this.props.emptyInput(email, error);
  }

  onEmailChange(text) {
    this.props.emailChanged(text);
  }

  onPasswordChange(text) {
    this.props.passwordChanged(text);
  }

  onButtonPress() {
      const { email, password } = this.props;
      this.props.loginUser({ email, password });
  }

  render() {
    console.log("render ediyorum");
    return(
      <View style={styles.viewStyle}>
        <FormLabel labelStyle={styles.labelStyle}>Email</FormLabel>
        <FormInput
          placeholder='Enter your email'
          keyboardType="email-address"
          containerStyle={styles.containerStyle}
          inputStyle={styles.inputStyle}
          onChangeText={this.onEmailChange.bind(this)}
          value={this.props.email}
        />
        <FormLabel labelStyle={styles.labelStyle}>Password</FormLabel>
        <FormInput
          placeholder='Enter a password'
          secureTextEntry={true}
          containerStyle={styles.containerStyle}
          inputStyle={styles.inputStyle}
          onChangeText={this.onPasswordChange.bind(this)}
          value={this.props.password}
        />
        <Text style={styles.errorTextStyle}>
          {this.props.error}
        </Text>
        <AuthButton
          title='Sign In'
          backgroundColor='#eb4454'
          onPress={this.onButtonPress.bind(this)}
        />
      </View>
    );
  }
}
const styles = {
  viewStyle: {
    top: SCREEN_HEIGHT * -0.15
  },
  containerStyle: {
    marginBottom: 10,
    width: SCREEN_WIDTH * 0.80,
    borderBottomColor: '#3c143c'
  },
  labelStyle: {
    color: '#3c143c',
    fontFamily: 'System',
    fontSize: 20
  },
  inputStyle: {
    color: '#3c143c',
    fontFamily: 'System',
    fontSize: 20
  },
  errorTextStyle: {
    fontSize: 20,
    alignSelf: 'center',
    color: 'red'
  }
}

const mapStateToProps = ({ auth }) => {
    const { email, password, error } = auth;

    return { email, password, error };
}

export default connect(mapStateToProps, { emailChanged, passwordChanged, loginUser, emptyInput })(SigninForm);

这是空的输入动作创建者代码;

export const emptyInput = (email, error) => {
  return(dispatch) => {
    dispatch({ type: EMPTY_INPUT });
  }
};

最后,reducer代码完成了真正的工作;

import {
  EMAIL_CHANGED,
  PASSWORD_CHANGED,
  CREATE_USER,
  CREATE_USER_SUCCESS,
  CREATE_USER_FAIL,
  LOGIN_USER,
  LOGIN_USER_FAIL,
  LOGIN_USER_SUCCESS,
  EMPTY_INPUT
} from '../actions/types';

const INITIAL_STATE = {
  email: '',
  password: '',
  user: null,
  error: '',
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case EMAIL_CHANGED:
      return {...state, email: action.payload };
    case PASSWORD_CHANGED:
      return {...state, password: action.payload };
    case CREATE_USER:
      return {...state, error: '' };
    case CREATE_USER_SUCCESS:
      return {...state, ...INITIAL_STATE, user: action.payload};
    case CREATE_USER_FAIL:
      return {...state, error: 'Authentication Failed!', password: ''};
    case LOGIN_USER:
      return {...state, error: ''};
    case LOGIN_USER_SUCCESS:
      return {...state, ...INITIAL_STATE, user: action.payload};
    case LOGIN_USER_FAIL:
      return {...state, error: 'Authentication Failed', password: ''};
    case EMPTY_INPUT:
        return {...state, ...INITIAL_STATE};
    default:
      return state;
  }
};