У меня есть экран входа в систему с двумя полями электронной почты и паролем, он работает нормально, но если пользователь вводит в любое поле, затем нажимает кнопку «Назад», чтобы перейти к предыдущему экрану, затем возвращается к экрану входа, экран должен быть сброшен и пустой, но содержит предыдущий пользовательский ввод.
Как я могу очистить/сбросить пользовательский ввод, т.е. (состояние/реквизит), когда пользователь нажимает кнопку «Назад» и экран закрывается. Я использую редукционный преобразователь, Реагировать на навигацию 3
Вот мой код для экрана входа в систему.
ЛогинЭкран
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;
}
};
Любая помощь будет принята с благодарностью!
Решение 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, когда вы нажимаете назад. текущий компонент будет размонтирован, это для родительских компонентов, и для решения этих проблем есть решение. вы можете использовать метод willfocus из реагирующей навигации
console.info что-нибудь внутри вашего события, чтобы увидеть себя ... и проверить это stackoverflow.com/questions/48018084/…
какую навигационную библиотеку вы используете? и если реагировать на навигацию, то какая версия?
Я думаю, что компонент размонтируется, сделайте одно... используйте локальное состояние в своем компоненте, посмотрите, сохранится ли оно при повторном посещении компонента.
Если компонент будет размонтирован, когда вы нажмете кнопку «Назад» в заголовке стека... тогда событие componentDidMount
должно запускаться каждый раз, когда вы возвращаетесь к нему... console.info в componentDidMount
должен все рассказать :)
Пожалуйста, поделитесь своим кодом на выставочной закуске, я постараюсь решить ее для вас :)
Привет @SarmadShah, большое спасибо за ответ. Когда я делаю const clearData = () => { type: "CLEAR" }
ничего не происходит, а в моем файле создателя действий написано, что ненужная метка "тип" и "ОЧИСТИТЬ" не является выражением или утверждением. Если я пытаюсь использовать диспетчеризацию в функции, она говорит, что диспетчеризация не является функцией.
@SarmadShah Я исправил проблему, которая была у меня в комментарии выше. Все, что мне нужно было сделать, это добавить возврат к создателю действия export const clearData = () => { return { type: CLEAR_DATA }; };
вам нужно обновить свой ответ, чтобы включить возврат, или вы можете сделать это без возврата. Большое спасибо Андрей
рад помочь, и помните, навигатор стека всегда размонтирует дочернее представление @hen
Но дело в том, что... в stackNavigator при переходе назад... компонент не будет размонтирован... он просто потеряет фокус... поэтому
clearData
вызываться не будет