Formik表单值未在react-native中使用ComponentDidUpdate()更新

时间:2019-05-09 13:14:59

标签: forms api react-native fetch formik

我在带有redux fetch api的react-native中使用formik形式。我有一个带有formik表单的主页,其中有2个输入,pickup location and dropoff location,OnPress我正在调用redux fetch API,它是post方法API,效果很好,但是在下一页中,我放置了输入,以便访问者可以更改dropoff location and pickup location

这就像更改设置,我现在用ComponentDidUpdate()更新它,但不是更新formik表单值,而是向我发送相同的先前值。不知道为什么。代码在下面。

以下是一些屏幕截图:

Homepage Screenshot

After Submit fetched data Screenshot

Settings Modal with Inputs OnChangeText Screenshot

After Updating Returns Previous Values Screenshot

代码如下:

Home.js

import React, { Component, Fragment, useState } from 'react';
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import NavigationService from './../../Navigation/NavigationService';
import { Formik } from 'formik';
import { Text, View, TouchableHighlight, Button } from 'react-native';
import { TextInput } from 'react-native-paper';
import { submitLocationToServer } from './../../../actions/instantPricesAction';

class Home extends Component {
    render() {
        return (
            <Formik
                initialValues={{ pickupLocation: '', dropoffLocation: '' }}

                onSubmit={values => {
                    this.props.submitLocationToServer(values, pickupDate);
                    NavigationService.navigate('ListPage', { formData: values });
                }
                }>
                {({ handleChange, handleSubmit, values, errors }) => (
                    <View>
                        <TextInput
                            value={values.pickupLocation}
                            onChangeText={handleChange('pickupLocation')}
                            label="Pickup Location"
                            placeholder="e.g, W10 4JA"
                        />
                        <TextInput
                            onChangeText={handleChange('dropoffLocation')}
                            value={values.dropoffLocation}
                            label="DropOff Location"
                            placeholder="e.g, SW12 6XD"
                        />
                        <Button title="Submit" onPress={handleSubmit} />
                    </View>
                )}
            </Formik>
        )
    }
}

const mapsStateToProps = (state, props) => {
    return {
        ...state.instantPrices,
        ...props
    };
}

const mapDispatchToProps = dispatch => bindActionCreators({
    submitLocationToServer
}, dispatch);

export default connect(mapsStateToProps, mapDispatchToProps)(Home);

List.js设置代码。 现在,在这里,我通过NavigationService getParams获得了以前的表单值。

import React, { Component } from 'react';
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import { View } from 'react-native';
import { submitLocationToServer } from './../../actions/instantPricesAction';
import { Input } from 'native-base';
import Modal from "react-native-modal";
import { Formik } from 'formik';
import { withNavigation } from 'react-navigation'

class VansFilterModal extends Component {

    componentDidUpdate() {
        const { pickupDate, submitLocationToServer, responseMsg } = this.props;
        (values) => submitLocationToServer(values, pickupDate);
        console.log(responseMsg._embedded);
    }

    getFilterModal() {
        const homeScreenData = this.props.navigation.getParam('formData');
        return (
            <Container style={styles.modal}>
                <Content style={{ marginTop: 40 }}>
                    <Formik
                        initialValues={{
                            pickuplocation: homeScreenData.pickupLocation,
                            dropofflocation: homeScreenData.dropoffLocation
                        }}
                    >
                        {({ handleChange, values }) => (
                            <View>
                                <Input
                                    value={values.pickuplocation}
                                    onChangeText={handleChange('pickuplocation')}
                                    placeholder="Pick up location"
                                />
                                <Input
                                    value={values.dropofflocation}
                                    onChangeText={handleChange('dropofflocation')}
                                    placeholder="Dropoff location"
                                />
                            </View>
                        )}
                    </Formik>
                </Content>
            </Container>
        )
    }

    render() {
        const filterModal = this.getFilterModal();
        const { visibleVansFilter, hideVansFilter } = this.props;
        return (
            <View>
                <Modal
                    isVisible={visibleVansFilter}
                    onBackdropPress={() => hideVansFilter()}
                >
                    {filterModal}
                </Modal>
            </View>
        )
    }

}

const mapStateToProps = (state, props) => ({
    ...state.instantPrices,
    ...props
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
    submitLocationToServer
}, dispatch)

export default withNavigation(connect(
    mapStateToProps,
    mapDispatchToProps
)(VansFilterModal));

Action.js

export const submitLocationToServer = (values, pickupDate) => {
    return dispatch => {
        dispatch(instantPricesLoading(true));
        let url = 'My Url';
        return fetch(url, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                'pickupLocation': values.pickupLocation,
                'dropoffLocation': values.dropoffLocation,
                'pickupDate': pickupDate
            }),
        })
            .then((response) => {

                dispatch(instantPricesLoading(false));
                dispatch(instantPricesError(false, ''));

                if (!response.ok) {
                    if (response.status === 401)
                        throw 'You need to login and try again';
                    else if (response.status >= 400 && response.status <= 500) // our error
                        throw response.json();
                    else
                        throw response.statusText;
                }

                return response;

            })
            .then((response) => response.json())
            .then((response) => {
                dispatch(instantPricesComplete(response));
            })
            .catch((promise) => {
                dispatch(instantPricesLoading(false));
                dispatch(instantPricesError(true, promise.toLocaleString()));
            });
    }
}

NavigationServie.js

import { NavigationActions } from 'react-navigation';

let _navigator;

const setTopLevelNavigator = (navigatorRef) => {
    _navigator = navigatorRef;
}

const navigate = (routeName, params) => {
    _navigator.dispatch(
        NavigationActions.navigate({
            routeName,
            params,
        })
    );
}

export default {
    navigate,
    setTopLevelNavigator,
};

1 个答案:

答案 0 :(得分:0)

请尝试

<Formik
      enableReinitialize 
      initialValues={{
          pickuplocation: homeScreenData.pickupLocation,
          dropofflocation: homeScreenData.dropoffLocation
        }}
>