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?
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!