web-dev-qa-db-ja.com

コンポーネントからReduxフォームに値を渡す方法

私はReact.jsのフォームにReduxフォームを使用していますが、フォームはlatとlongをフォームにバインドしたいカスタムのgoogle mapコンポーネントを持っています

フォーム

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;

このコンポーネントは、ユーザーがマーカーをドラッグすると、lat。とlongの値をconsole.logに記録します

console.log値をredux-formに渡す方法は?

誰かがそうする方法を提案できますか?

10
User_3535

ここ は、redux-formを使用するアプリのコードサンドボックスです。 latLngForm.jsでフォームを設定した後、マップコンテナーでconnectを使用して、マーカーが移動したときにdispatch reduxFormのchangeアクションを実行します。これがストアを更新するものです。

また、positionpropとして<MyMapComponent />に渡して、マーカーの位置を設定します。つまり、マーカーの位置は常にフォームの値に基づいており、マップのマーカーを移動するとフォームの値が手動で変更されます。これにより、フィールドを使用して手動で、またはマーカーをドラッグアンドドロップして位置を設定できます。

<MyMapComponent />mapStateToPropsは、ここで重要な部分です。 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を介してフィールドを使用できるようになりました。

9
NorianNyx

ここ は、サンドボックスから分岐した私の実用的なソリューションです。

マーカーの位置が変わるたびに発生するMyParentComponentWrapperコンポーネントにコールバックを追加しました。フォームでは、コールバックをリッスンし、positionフィールドにMyParentComponentWrapperから受け取った値を設定します。

私はコンポーネントをできるだけシンプルに保ち、connectを介してコンポーネントをredux状態に接続しないようにします。 MyParentComponentWrapperは、この値がどのように/どこで使用されるかを意識せずに、値が変更されるたびにchangeイベントのみを発生させる入力フィールドと考えてください。

この場合、MyParentComponentWrapperはマーカーを表示し、マーカーの位置が変わるたびにコールバックを呼び出します。この位置を適切に処理するのはフォームコンポーネントです。

これが、コールバックを使用してフォームのレンダリングを変更した方法です。

<MyParentComponentWrapper setPosition={onPositionSet} />

フォームコンポーネントのコールバックは次のとおりです。

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

change関数は、redux-formでラップしたときにコンポーネントの小道具に追加されました

0
Dario