Redux показывает старое состояние при повторном открытии экрана

У меня есть экран входа в систему с двумя полями электронной почты и паролем, он работает нормально, но если пользователь вводит в любое поле, затем нажимает кнопку «Назад», чтобы перейти к предыдущему экрану, затем возвращается к экрану входа, экран должен быть сброшен и пустой, но содержит предыдущий пользовательский ввод.

Как я могу очистить/сбросить пользовательский ввод, т.е. (состояние/реквизит), когда пользователь нажимает кнопку «Назад» и экран закрывается. Я использую редукционный преобразователь, Реагировать на навигацию 3

Redux показывает старое состояние при повторном открытии экрана

Вот мой код для экрана входа в систему.

ЛогинЭкран

class LoginScreen extends Component {
    constructor(props) {
    super(props);
    this.unsubscriber = null;
}

componentWillUnmount(): void {
    if (this.unsubscriber) {
    this.unsubscriber();
    }
}

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

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

onConfirmPasswordChange(text) {
    this.props.confirmPasswordChanged(text);
}

onLoginButtonPress() {
    let {email, password} = this.props;
    let currentAnonymousFirebaseUser = firebase.auth().currentUser;
    this.props.loginUser({email, password, currentAnonymousFirebaseUser});
}

renderError() {
    if (this.props.error) {
      return (
        <View
          style = {{backgroundColor: "#fff", paddingBottom: 5, paddingTop: 5}}>
          <Text style = {styles.errorTextStyle}>{this.props.error}</Text>
        </View>
      );
    }
}

renderLoginButton() {
    if (this.props.loading) {
        return <Spinner size = "large" />;
    }
    return <Button onPress = {() => this.onLoginButtonPress()}>Login</Button>;
}

render() {
    return (
      <Card>
        <CardSection>
          <Row>
            <Input
              label = "Email"
              placeholder = "[email protected]"
              onChangeText = {this.onEmailChange.bind(this)}
              value = {this.props.email}
            />
          </Row>
        </CardSection>

        <CardSection>
          <Row>
            <Input
              secureTextEntry
              label = "Password"
              placeHolder = "password"
              onChangeText = {this.onPasswordChange.bind(this)}
              value = {this.props.password}
            />
          </Row>
        </CardSection>

        {this.renderError()}

        <CardSection>
          <Row>{this.renderLoginButton()}</Row>
        </CardSection>
      </Card>
      );
   }
}

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

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

Редуктор

const INITIAL_STATE = {
    email: "",
    password: "",
    confirmPassword: "",
    user: null,
    error: "",
    loading: false
};

export default (state = INITIAL_STATE, action) => {
    console.info(action);

    switch (action.type) {
        case EMAIL_CHANGED:
          return {...state, email: action.payload};

        case PASSWORD_CHANGED:
          return {...state, password: action.payload};

        case CONFIRM_PASSWORD_CHANGED:
          return {...state, confirmPassword: action.payload};

        case CREATE_USER_ACCOUNT:
          return {...state, loading: true, error: ""};

        case CREATE_USER_ACCOUNT_SUCCESS:
          return {...state, ...INITIAL_STATE, user: action.payload};

        case CREATE_USER_ACCOUNT_FAIL:
          return {...state, error: action.payload, loading: false};

       case LOGIN_USER:
          return {...state, loading: true, error: ""};

        case LOGIN_USER_ANONYMOUSLY:
          return {...state};

        case LOGIN_USER_SUCCESS:
          return {...state, ...INITIAL_STATE, user: action.payload};

        case LOGIN_USER_FAIL:
          return {...state, error: action.payload, loading: false};

        default:
          return state;
    }
};

Любая помощь будет принята с благодарностью!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
0
1 874
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Решение 1

Добавьте параметр reset к вашему LoginScreen при переходе к нему:

class LoginScreen extends React.Component {
  componentWillReceiveProps(nextProps) {
    const nextReset = nextProps.navigation.getParam("reset");
    const reset = this.props.navigation.getParam("reset");

    if (nextReset && nextReset !== reset) {
      // Create  a redux action to clear field values:
      nextProps.resetFieldsAction();
    }
  }
}

Вот как вы переходите к своему LoginScreen:

this.props.navigation.navigate("LoginScreen", { reset: true });

Решение 2

import {NavigationEvents} from 'react-navigation';

Добавьте этот компонент в свой метод рендеринга и вызовите свой redux action, когда ваш компонент снова получит фокус:

<NavigationEvents onDidFocus = {() => this.props.resetFieldsAction()} />
Ответ принят как подходящий

Вы можете сделать еще одно действие для очистки ваших данных в редуксе, Например

const clearData = () => {
  return{
  type: "CLEAR"
 };
};

и в вашем редукторе вы можете просто использовать этот clearData, Например

 case "CLEAR"
 return {...state, ...INITIAL_STATE}

или

 case "CLEAR"
 return {...state, email: INITIAL_STATE.email}

Это зависит от вашего варианта использования. Когда все сделано.

Просто вызовите это действие на своем componentWillUnmount на экране входа в систему.

Например

componentWillUnmount() {
 this.props.clearData();
}

Но дело в том, что... в stackNavigator при переходе назад... компонент не будет размонтирован... он просто потеряет фокус... поэтому clearData вызываться не будет

Hend El-Sahli 09.04.2019 20:21

в stacknavigator, когда вы нажимаете назад. текущий компонент будет размонтирован, это для родительских компонентов, и для решения этих проблем есть решение. вы можете использовать метод willfocus из реагирующей навигации

Sarmad Shah 09.04.2019 20:22

console.info что-нибудь внутри вашего события, чтобы увидеть себя ... и проверить это stackoverflow.com/questions/48018084/…

Hend El-Sahli 09.04.2019 20:25

какую навигационную библиотеку вы используете? и если реагировать на навигацию, то какая версия?

Sarmad Shah 09.04.2019 20:28

Я думаю, что компонент размонтируется, сделайте одно... используйте локальное состояние в своем компоненте, посмотрите, сохранится ли оно при повторном посещении компонента.

Sarmad Shah 09.04.2019 20:29

Если компонент будет размонтирован, когда вы нажмете кнопку «Назад» в заголовке стека... тогда событие componentDidMount должно запускаться каждый раз, когда вы возвращаетесь к нему... console.info в componentDidMount должен все рассказать :)

Hend El-Sahli 09.04.2019 20:34

Пожалуйста, поделитесь своим кодом на выставочной закуске, я постараюсь решить ее для вас :)

Sarmad Shah 09.04.2019 20:36

Привет @SarmadShah, большое спасибо за ответ. Когда я делаю const clearData = () => { type: "CLEAR" } ничего не происходит, а в моем файле создателя действий написано, что ненужная метка "тип" и "ОЧИСТИТЬ" не является выражением или утверждением. Если я пытаюсь использовать диспетчеризацию в функции, она говорит, что диспетчеризация не является функцией.

Andrew Irwin 10.04.2019 11:55

@SarmadShah Я исправил проблему, которая была у меня в комментарии выше. Все, что мне нужно было сделать, это добавить возврат к создателю действия export const clearData = () => { return { type: CLEAR_DATA }; }; вам нужно обновить свой ответ, чтобы включить возврат, или вы можете сделать это без возврата. Большое спасибо Андрей

Andrew Irwin 10.04.2019 12:19

рад помочь, и помните, навигатор стека всегда размонтирует дочернее представление @hen

Sarmad Shah 10.04.2019 12:39

Другие вопросы по теме