2017-11-09 3 views
0

Googleマップの子コンポーネント「PlotMap」を持つReduxフォームコンポーネントがあります。子コンポーネントは、マップ入力をコールバックのオブジェクトとして戻します。私はこのマップ入力オブジェクトをフォームデータに含めます。それ、どうやったら出来るの?隠しフィールドを使用しますか? Reduxフォームの驚異的な動作は私には不透明なので、オブジェクトを追加する場所がわかりません。ReduxForm:子コンポーネントからのマップ入力の追加

PlotFormコンポーネント:

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { Field, reduxForm } from 'redux-form'; 
import * as actions from '../../actions'; 
import { Link } from 'react-router'; 
import PlotMap from './plotMap'; 

const renderField = ({ 
    input, 
    label, 
    type, 
    meta: { touched, error, warning } 
}) => (
    <fieldset className="form-group"> 
     <label htmlFor={input.name}>{label}</label> 
     <input className="form-control" {...input} type={type} /> 
     {touched && error && <span className="text-danger">{error}</span>} 
    </fieldset> 
); 

class PlotForm extends Component { 
    constructor(props) { 
     super(props); 
     this.handleFormSubmit = this.handleFormSubmit.bind(this); 
    } 

    handleFormSubmit(props) { 
     this.props.addPlot(props); 
    } 

    render() { 
     const { handleSubmit } = this.props; 
     const user = JSON.parse(localStorage.getItem('user')); 
     return (
      <div className="form-container text-center"> 
       <form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}> 
        <Field 
         name="name" 
         component={renderField} 
         type="text" 
         label="Plot Name" 
        /> 
        {user && 
         user.role === 3 && (
          <Field 
           name="company" 
           component={renderField} 
           type="text" 
           label="Company" 
          /> 
         )} 
        <Field 
         name="grower" 
         component={renderField} 
         type="text" 
         label="Grower" 
        /> 
        <Field 
         name="variety" 
         component={renderField} 
         type="text" 
         label="Variety" 
        /> 
        <Field 
         name="variety2" 
         component={renderField} 
         type="text" 
         label="Variety 2" 
        /> 
        <Field 
         name="planted" 
         component={renderField} 
         type="date" 
         label="Date Planted" 
        /> 
        <hr /> 
        <PlotMap getGeoJSON={GeoJSON => console.log(GeoJSON)} /> 
        <div className="form-group"> 
         <span> 
          <label>&nbsp;</label> 
          <button type="submit" className="btn btn-primary"> 
           Add Plot 
          </button> 
         </span> 
        </div> 
       </form> 
       <hr /> 
       <div> 
        {this.props.errorMessage && 
         this.props.errorMessage.plots && (
          <div className="error-container"> 
           Oops! {this.props.errorMessage.plots} 
          </div> 
         )} 
       </div> 
      </div> 
     ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
     errorMessage: state.plots.error 
    }; 
} 

PlotForm = reduxForm({ form: 'plot', validate })(PlotForm); 
export default connect(mapStateToProps, actions)(PlotForm); 

PlotMapコンポーネント:あなたが知っているように

import React, { Component } from 'react'; 
const { compose, withProps } = require('recompose'); 
const { withScriptjs, withGoogleMap, GoogleMap } = require('react-google-maps'); 
const { 
    DrawingManager 
} = require('react-google-maps/lib/components/drawing/DrawingManager'); 

const editTrack = polygon => { 
    let GeoJSON = { 
     type: 'Feature', 
     geometry: { 
      type: 'Polygon', 
      coordinates: [] 
     }, 
     properties: {} 
    }; 
    for (let point of polygon.getPath().getArray()) { 
     GeoJSON.geometry.coordinates.push([point.lng(), point.lat()]); 
    } 
    return GeoJSON; 
}; 

const PlotMap = compose(
    withProps({ 
     googleMapURL: 
      'https://maps.googleapis.com/maps/api/js?key=myKey&v=3.exp&libraries=geometry,drawing,places', 
     loadingElement: <div style={{ height: `100%` }} />, 
     containerElement: <div style={{ height: `400px` }} />, 
     mapElement: <div style={{ height: `100%` }} /> 
    }), 
    withScriptjs, 
    withGoogleMap 
)(props => (
    <GoogleMap 
     defaultZoom={8} 
     defaultCenter={new google.maps.LatLng(32.095, 35.398)}> 
     <DrawingManager 
      onPolygonComplete={polygon => { 
       polygon.setEditable(true); 
       props.getGeoJSON(editTrack(polygon)); 
       google.maps.event.addListener(polygon.getPath(), 'insert_at', function(
        index, 
        obj 
       ) { 
        props.getGeoJSON(editTrack(polygon)); 
       }); 
       google.maps.event.addListener(polygon.getPath(), 'set_at', function(
        index, 
        obj 
       ) { 
        props.getGeoJSON(editTrack(polygon)); 
       }); 
      }} 
      defaultDrawingMode={google.maps.drawing.OverlayType.POLYGON} 
      defaultOptions={{ 
       drawingControl: true, 
       drawingControlOptions: { 
        style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, 
        position: google.maps.ControlPosition.TOP_CENTER, 
        drawingModes: [google.maps.drawing.OverlayType.POLYGON] 
       } 
      }} 
     /> 
    </GoogleMap> 
)); 

export default PlotMap; 
+0

私はPlotMapのインタフェース(小道具)についての詳細情報を必要としています。 –

+1

'const user = JSON.parse(localStorage.getItem( 'user'));'を 'componentWillMount()'またはコンストラクタに移動すると、各レンダリングでそれを呼び出さないでください。さらに、これを処理するreduxミドルウェアを作成し、それをストアにロードします。 –

+0

ありがとう、@ OriDrori。 PlotMapのコードを追加しました。基本的にポリゴンオブジェクトを最初に作成した後、編集した後、コールバックを起動して新しいGeoJSONオブジェクトを作成して返します。 –

答えて

2

、あなたはFieldからcomponent小道具としてステートレス機能( "renderField")を渡すことができます。関数内にPlotMapをラップし、onChangeハンドラーのみをgetGeoJSONに接続できます。

onChange方法は、以下のように記載されている:

onChangeイベントは、基礎となる入力から 焼成されたときに呼び出されるコールバック。

このコールバックは、フィールドコンテンツが変更されたことをredux-formに通知し、これはreduxストアを更新します。 onChangeイベントを使用して呼び出す代わりに、手動で呼び出してデータを渡すことができます。

例Reduxのフォーム(未テスト):

<Field name="plotMap" component={({ input }) => (
    <PlotMap getGeoJSON={input.onChange} /> 
)}/> 
+0

ここでinput.onChangeパラメータがどのように機能するのか説明できますか? –

+0

また、フォームが送信されると、GeoJSONオブジェクトはreq.body.plotMapとしてアクセス可能になりますか? –

+1

私はいくつかの情報を追加します。これは、標準的なレピュックス形式のフィールドなので、それはできます。 –

関連する問題