Как сохранить значение TextInput в бумаге React-Native? - PullRequest
0 голосов
/ 31 января 2020

У меня есть два экрана, A и B. Экран A содержит только TextInput с реагирующей нативной бумагой, например,

            <View>
                <TextInput
                    error={error}
                    label='Enter something'
                    mode='outlined'
                    onBlur={this.onBlurHandler}
                    onChangeText={text => this.setState({text})}
                    value ={this.state.text}
                />
            </View> 

В вышеприведенном случае, когда я перехожу с экрана A на экран B, и если я нажму назад, чтобы перейти к экрану A, значение TextInput уйдет, хотя this.state.text содержит те данные, которые я заполнил на экране A.

Если я жестко закодировал значение, то оно останется сохраненным после перехода из A на B и затем обратно на AEg,

    <View>
        <TextInput
            error={error}
            label='Enter something'
            mode='outlined'
            onBlur={this.onBlurHandler}
            onChangeText={text => this.setState({text})}
            value ={'Hello World'}
        />
    </View> 

Скажите, пожалуйста, как я могу убедиться, что значение TextInput сохраняется при переходе с экрана B на экран A. Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 31 января 2020

Исходя из того, что вы сказали, экран A не отключается и, даже если значение в this.state.text остается нетронутым, графически значение было очищено. В моем случае все работает как положено.

ScreenA

import React, { Component } from "react";
import { TextInput } from "react-native-paper";

export default class ScreenA extends Component {
    constructor(props) {
        super(props);
        this.state = { text: "" };
    }
    render() {
        return (
            <TextInput
                error={false}
                label="Enter something"
                mode="outlined"
                onChangeText={text => this.setState({ text })}
                onBlur={() => this.props.navigation.navigate("ScreenB")}
                value={this.state.text}
            />
        );
    }
}

ScreenB

import React, { Component } from "react";
import { Text, View } from "react-native";

export default class LoadingScreen extends Component {
    render() {
        return (
            <View>
                <Text> ScreenB </Text>
            </View>
        );
    }
}

Navigator

const RoutesConfig = {
    ScreenA: {
        screen: ScreenA,
    },
    ScreenB: {
        screen: ScreenB,
    }
};

const StackNavigatorConfigs = {
    initialRouteName: "ScreenA",
};

export default createStackNavigator(RoutesConfig, StackNavigatorConfigs);

В режиме ScreenA я пишу все, что мне нужно, а затем перехожу к ScreenB, когда TextInput вызывает onBlur. Используя StackNavigator Header, я возвращаюсь назад, и значение все еще сохраняется и отображается в TextInput.

Если значение все еще сохраняется в state (если я правильно понял, что это так) Вы можете использовать withNavigationFocus HO C, предоставленный react.navigation. Используя это, вы можете увидеть, действительно ли значение сохранено, и посмотреть, будет ли при повторном рендеринге отображаться значение графически.

Например, используя мой ScreenA sample:

import React, { Component } from "react";
import { TextInput } from "react-native-paper";
import { withNavigationFocus } from "react-navigation";

class ScreenA extends Component {
    constructor(props) {
        super(props);
        this.state = { text: "" };
    }

    componentDidUpdate = (prevProps) => { 
        if ( prevProps.isFocused === false && this.props.isFocused === true ){
            this.setState({ text : this.state.text })
        }
    }

    render() {
        return (
            <TextInput
                error={false}
                label="Enter something"
                mode="outlined"
                onChangeText={text => this.setState({ text })}
                onBlur={() => this.props.navigation.navigate("ScreenB")}
                value={this.state.text}
            />
        );
    }
}

export default withNavigationFocus(ScreenA);
0 голосов
/ 31 января 2020

Обычно я использую избыточность для хранения значений, что помогает в этой ситуации. Redux , React Redux

//reducers/inputReducer.js
import {
   UPDATE_INPUT
} from '../actions'

const initialState = {
   input = null
}

function input(state = initialState, action) {
    switch (action.type) {
        case UPDATE_INPUT: {
           return {
               ...state,
               input = action.value
           }
        }
        default:
            return state;
    }
}
export default input
//input.js
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { updateInput } from './actions.js'
...
<TextInput
            error={error}
            label='Enter something'
            mode='outlined'
            onBlur={this.onBlurHandler}
            onChangeText={text => this.props.updateInput(text)}
            value ={this.props.input}
        />
...
function mapStateToProps(state) {
    return {
        input: state.input
    }
}

function matchDispatchToProps(dispatch) {
    return bindActionCreators(
        {
           updateInput
        },
        dispatch
    );
}

export default connect(mapStateToProps, matchDispatchToProps)(input);
//actions.js

export const UPDATE_INPUT = "UPDATE_INPUT";
export function updateInput(value) {
    return {
        type: UPDATE_INPUT,
        value: value
    }
}

Обратите внимание, вам все еще нужно настроить хранилище и редуктор,

Редактировать: Другая часть настройки redux (надеюсь, я ничего не пропустил)

//store.js
import { createStore } from 'redux';
import combineReducers from './reducers';

const store = createStore(combineReducers);

export default store;
//reducers/index.js
import { combineReducers } from 'redux';
import input from './inputReducer';

export default combineReducers({
  input
});
//index.js

import { Provider } from 'react-redux';
import store from './store';

ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));

...