Как передать значения из компонента в форму Redux
Я использую форму Redux для формы в React.js, и моя форма была, и у меня есть пользовательский компонент карты Google, я хочу привязать lat и long к моей форме
форма
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);
и мой код MyParentComponentWrapper был
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;
этот компонент будет console.log значений lat и long, когда пользователь перетаскивает маркер
Как сдать console.log
значение для редукс-формы?
Кто-нибудь может предложить, пожалуйста, способ сделать это?
3 ответа
Вот коды и коробка вашего приложения, использующего redux-form
, Обратите внимание, что после настройки формы в latLngForm.js
, Я использую connect
в контейнере вашей карты, чтобы dispatch
reduxForm-х change
действие, когда ваш маркер перемещается. Это то, что обновляет магазин.
Я тоже прохожу position
в качестве prop
в <MyMapComponent />
установить положение вашего маркера. Это означает, что положение вашего маркера всегда основано на значениях формы, и что перемещение маркеров карты вручную изменяет значение формы. Это позволит вам установить положение вручную с помощью полей или перетаскивая маркер.
mapStateToProps
в <MyMapComponent />
это важная часть здесь. redux-form
автоматически сохраняет значения в состоянии для нас, это где мы получаем его.
Обратите внимание на эти строки в верхней части файла:
import { change, formValueSelector } from "redux-form";
...
const formSelector = formValueSelector("form");
Это устанавливает наш селектор форм. "form"
быть идентификатором для формы. Теперь, чтобы извлечь эти значения из нашего состояния, мы делаем:
const mapStateToProps = (state) => ({
position: {
lat: formSelector(state, 'lat'),
lng: formSelector(state, 'lng') // The key here is the name you passed into the field.
}
});
Тогда мы используем connect
чтобы реально подключить компонент к магазину:
connect(mapStateToProps)(MyMapComponent);
Redux делает свое волшебство, и теперь наши поля доступны через this.props.position
в нашей составляющей!
Для функциональных компонентов вы можете сделать это:
useEffect(()=>{
dispatch(change("travellerDetailsForm", "dob", "DD/MM/YYYY"));
},[])
или вы можете сделать это в обработчике изменений с таким событием:
const panNameChangeHandler = (e) => {
e.preventDefault();
const panName = e.target.value.toUpperCase();
dispatch(change("travellerDetailsForm", "name", panName));
};
Вот мое рабочее решение, раздвоенное из вашей песочницы.
Я только что добавил обратный звонок в ваш MyParentComponentWrapper
компонент, который запускается каждый раз, когда изменяется положение маркера. В вашей форме вы слушаете обратный вызов и устанавливаете position
поле со значением, полученным от MyParentComponentWrapper
,
Мне нравится, чтобы компоненты были как можно проще и не связывать их с избыточным состоянием через connect
, Просто подумай о своем MyParentComponentWrapper
в качестве поля ввода, которое только запускает change
событие каждый раз, когда его значение изменяется, не зная, как / где это значение будет использоваться.
В этом случае MyParentComponentWrapper
просто показать маркер и вызывает обратный вызов каждый раз, когда позиция маркера изменяется. Именно компонент формы отвечает за правильное обращение с этой позицией.
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);
}
где change
function has been added to your component props as you wrapped it in a redux-form