How to pass values from on component to Redux form
Asked Answered
B

3

11

I am using Redux form for form in React.js and my form was and I have a custom google map component I want to bind lat and long to my form

form

import React from 'react';
import { Field, reduxForm } from 'redux-form';
const SimpleForm = props => {
  const { handleSubmit, pristine, reset, submitting } = props;
  return (
    <form onSubmit={handleSubmit}>
      <div className="position-relative form-group">
        <label>First Name</label>
        <div>
          <Field
            name="firstName"
            component="input"
            type="text"
            placeholder="First Name"
            className="form-control"
          />
        </div>
      </div>
<Field name = 'eventLocation'
        component = {MyParentComponentWrapper} />
</form>
  );
};
export default reduxForm({
  form: 'simple', // a unique identifier for this form
})(SimpleForm);

and my MyParentComponentWrapper code was

import React from 'react';
import { compose, withProps, lifecycle } from 'recompose';
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from 'react-google-maps';

const MyMapComponent = compose(
    withProps({
        googleMapURL:
            'https://maps.googleapis.com/maps/api/js?key=AIzaSyCYSleVFeEf3RR8NlBy2_PzHECzPFFdEP0&libraries=geometry,drawing,places',
        loadingElement: <div style={{ height: `100%` }} />,
        containerElement: <div style={{ height: `400px` }} />,
        mapElement: <div style={{ height: `100%` }} />,
    }),
    lifecycle({
        componentWillMount() {
            const refs = {};

            this.setState({
                position: null,
                onMarkerMounted: ref => {
                    refs.marker = ref;
                },

                onPositionChanged: () => {
                    const position = refs.marker.getPosition();
                    console.log(position.toString());
                },
            });
        },
    }),
    withScriptjs,
    withGoogleMap
)(props => (
    <GoogleMap defaultZoom={8} defaultCenter={{ lat: -34.397, lng: 150.644 }}>
        {props.isMarkerShown && (
            <Marker
                position={{ lat: -34.397, lng: 150.644 }}
                draggable={true}
                ref={props.onMarkerMounted}
                onPositionChanged={props.onPositionChanged}
            />
        )}
    </GoogleMap>
));

class MyParentComponentWrapper extends React.PureComponent {
    state = {
        isMarkerShown: false,
    };

    render() {
        return (
            <div>
                <MyMapComponent isMarkerShown={true} />
            </div>
        );
    }
}

export default MyParentComponentWrapper;

this component will console.log the lat and long values when user drag the marker

How to pass the console.log value to redux-form?

Can anyone please suggest a way to do so?

Brig answered 5/7, 2018 at 20:11 Comment(10)
Instead of getting the logged value, you could not log it and then save it in some variable or state object.Corny
Create Field with Component wich will be GoogleMapFletcher
i created google map Component but i can"t able to pass the value to redux-form ., my google map Component code codesandbox.io/s/nkvjyppzomBrig
You should put position in your store and pass it into your form as a prop, then just set the value prop on the field.Antimatter
exactly i want that .,can you show a sample code in sandbox.io ?Brig
Sure. Could you add your form (and its implementation) on your sandbox.io example? I'm not sure where your form is being included here.Antimatter
@Brig I've forked your initial sandbox here with what I believe you may be trying to do. Keep in mind, this solution does not use reduxForm.Antimatter
my simple redux form ., codesandbox.io/s/mZRjw05yp., i want to implement this map component codesandbox.io/s/kkn6rkmwvv to redux formBrig
@Brig You have not set up your app to support Redux, and therefore cannot use redux-form. If you want to see an example of how this works without Redux, then you can look at the codesandbox that I have created here.Antimatter
take a look at this i implemented your map component to redux form but i can"t able to get values in redux form codesandbox.io/s/nkploj0nw0Brig
A
10

Here is a codesandbox of your app using a redux-form. Notice that after setting up the form in latLngForm.js, I use connect in your map container to dispatch reduxForm's change action when your marker is moved. This is what updates the store.

I also pass position in as a prop to <MyMapComponent /> to set the position of your marker. This means that your marker's position is always based off of the form's values, and that moving the map's markers manually changes the form's value. This will allow you to set the position manually via the fields, or by dragging and dropping the marker.

mapStateToProps in the <MyMapComponent /> is the important piece here. redux-form automatically stores the values in the state for us, this is where we retrieve it.

Notice these lines at the top of the file:

import { change, formValueSelector } from "redux-form";
...
const formSelector = formValueSelector("form");

This sets up our form selector. "form" being the identifier for the form. Now, to retrieve these values from our state, we do:

const mapStateToProps = (state) => ({
    position: {
        lat: formSelector(state, 'lat'),
        lng: formSelector(state, 'lng') // The key here is the name you passed into the field.
    }
});

Then we use connect to actually connect the component to the store:

connect(mapStateToProps)(MyMapComponent);

Redux does its magic and now our fields are available via this.props.position in our component!

Antimatter answered 11/7, 2018 at 21:54 Comment(0)
O
0

Here is my working solution, forked from your sandbox.

I just added a callback in your MyParentComponentWrapper component which is fired every time the marker position changes. In your form, you listen to the callback and set the position field with the value received from MyParentComponentWrapper.

I like to keep components as simpler as possible and not to connect them with redux state via connect. Just think of your MyParentComponentWrapper as an input field which only fires change event every time its value changes without being aware of how/where this value will be used.

In this case MyParentComponentWrapper just show a marker and invokes a callback every time marker position changes. It's the form component the one in charge of handling this position in the proper way.

Here's the how I changed your form render with the callback:

<MyParentComponentWrapper setPosition={onPositionSet} />

and here's the callback in your form component:

const onPositionSet = (position) => {
    props.change("position", position);
}

where change function has been added to your component props as you wrapped it in a redux-form

Ovariectomy answered 12/7, 2018 at 10:36 Comment(0)
I
0

For functional components you can do this:

useEffect(()=>{
        dispatch(change("travellerDetailsForm", "dob", "DD/MM/YYYY"));
    },[])

or you can do it in the change handler with the event too like this-

  const panNameChangeHandler = (e) => {
    e.preventDefault();
    const panName = e.target.value.toUpperCase();
    dispatch(change("travellerDetailsForm", "name", panName));
  };
Influence answered 27/7, 2022 at 13:7 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.