Zain Shabir
Zain Shabir

Reputation: 35

Formik form values not updating with ComponentDidUpdate() in react-native

I am using formik form in react-native with redux fetch API. I have a homepage with formik form there are 2 inputs, pickup location and dropoff location, OnPress I'm calling redux fetch API, It's post method API, It worked good, but on next page, I've put inputs so visitor can change dropoff location and pickup location.

It's like change settings, I'm now updating it with ComponentDidUpdate(), But It's not updating the formik form values, It's sending me the same previous values. Don't know why. Code is below.

Here are some screenshots:

Homepage Screenshot

After Submit fetched data Screenshot

Settings Modal with Inputs OnChangeText Screenshot

After Updating Returns Previous Values Screenshot

Here is the code:

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 Settings Code. Now here, I am getting the previous forms values via 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,
};

Upvotes: 1

Views: 1663

Answers (1)

anil kumar
anil kumar

Reputation: 19

Please try

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

Upvotes: 1

Related Questions