如何将值从一个组件传递到Redux表单

11

我正在使用Redux表单来创建React.js中的表单,我的表单中有一个自定义的谷歌地图组件,我想将纬度和经度绑定到我的表单中。

表单

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 打印经纬度值

如何将 console.log 的值传递到 redux-form 中?

有人能否建议一种解决方案?


不要获取已记录的值,而是可以不记录它,然后将其保存在某个变量或状态对象中。 - Andria
创建一个带有组件的字段,该组件将是Google地图。 - Nugzar Gaguliya
1
你应该将 position 放入你的 store 中,并将其作为 prop 传递到你的表单中,然后只需在字段上设置 value prop 即可。 - NoxelNyx
我的简单Redux表单。https://codesandbox.io/s/mZRjw05yp。我想将此地图组件https://codesandbox.io/s/kkn6rkmwvv实现到Redux表单中。 - User_3535
@User_3535 您尚未设置应用程序以支持Redux,因此无法使用redux-form。如果您想查看如何在没有Redux的情况下使用它的示例,则可以查看我创建的这里的codesandbox。 - NoxelNyx
显示剩余5条评论
3个回答

10

这里有您的应用程序的codesandbox,使用redux-form。请注意,在latLngForm.js中设置表单后,我在您的地图容器中使用connectdispatch reduxForm的change操作时,这就是更新存储库的方法。

我还将position作为一个prop传递给<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 将组件实际连接到 store:

connect(mapStateToProps)(MyMapComponent);

Redux施展其魔力,现在我们的字段可以通过this.props.position在组件中使用!


0

对于功能组件,您可以这样做:

useEffect(()=>{
        dispatch(change("travellerDetailsForm", "dob", "DD/MM/YYYY"));
    },[])

或者你也可以在事件的更改处理程序中这样做 -

  const panNameChangeHandler = (e) => {
    e.preventDefault();
    const panName = e.target.value.toUpperCase();
    dispatch(change("travellerDetailsForm", "name", panName));
  };

0

这里是我的工作解决方案,从你的沙盒分支出来。

我在你的MyParentComponentWrapper组件中添加了一个回调,它会在标记位置更改时触发。在你的表单中,你监听这个回调,并使用从MyParentComponentWrapper接收到的值设置position字段。

我喜欢尽可能保持组件的简单性,不通过connect将它们与redux状态连接起来。只需将你的MyParentComponentWrapper视为一个输入字段,每当它的值发生变化时仅触发change事件,而不知道如何/在哪里使用这个值。

在这种情况下,MyParentComponentWrapper只显示一个标记并在标记位置更改时调用回调。对于处理该位置的正确方法,由表单组件负责。

这是我的更改后的表单渲染:

<MyParentComponentWrapper setPosition={onPositionSet} />

以下是你的表单组件中的回调函数:

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

在你将组件包装在redux-form中后,change函数已被添加到你的组件属性中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接