Как передать значения из компонента в форму 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

Другие вопросы по тегам