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?
There are two methods to reinitialize the form component with new "pristine" values: Pass a enableReinitialize prop or reduxForm() config parameter set to true to allow the form the reinitialize with new "pristine" values every time the initialValues prop changes.
The connect() function connects a React component to a Redux store. It provides its connected component with the pieces of the data it needs from the store, and the functions it can use to dispatch actions to the store.
As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With