Невозможно получить корректную работу формы-редуктора formValueSelector - PullRequest
0 голосов
/ 05 апреля 2020

Мне трудно заставить formValueSelector из redux-form (v8.3) работать. Я перепробовал все варианты, которые я могу найти с помощью селектора внутри и снаружи `` `mapStateToProps``.

В этом компоненте я получаю значение для поля 'radius' (число) и повторно использую его для изменить размер круга листовки на карте.

import React, { Fragment, useRef } from "react";
import L from "leaflet";
import { connect, useDispatch } from "react-redux";
import { change } from "redux-form";
import { useLeaflet } from "react-leaflet";
import AdjustIcon from '@material-ui/icons/Adjust';
import MapButton from "./MapButton";
import { Grid, Typography, Popover, Button } from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles'
import { RenderTextField, } from 'components/form/FormFields'
import { Field } from 'redux-form'
import { firestoreConnect } from 'react-redux-firebase'
import { compose } from 'redux'
import { reduxForm, formValueSelector } from 'redux-form'
import { networkStatus } from 'actions/onlineStatus'
import { handleFormAdd } from 'actions/formActions'
import { withSnackbar } from 'notistack'

const useStyles = makeStyles(theme => ({
  legend: {
    padding: theme.spacing(1, 0.5),
    borderRadius: '4px',
    boxShadow: '0 1px 5px rgba(0, 0, 0, 0.65)'
  },
  list: {
    padding: theme.spacing(1)
  },
  row: {
    verticalAlign: 'middle',
    margin: theme.spacing(0, 0, 0.5, 0),
    height: '24px',
    fontSize: '13px'
  }
}))

const formName = 'geopoints'

function Circle(props) {
  const {
    handleSubmit,
    radius,
    pristine,
    reset,
    submitting
  } = props

  console.log(radius)

  const onSubmit = formProps => {
    const data = Object.assign(
      {
        author: props._userUID,
        authorName: props._authorName,
        createdAt: new Date().getTime()
      },
      formProps
    )
    props
      .networkStatus()
      .then(() => {
        props.handleFormAdd(
          {
            formName: formName,
            formData: data
          },
          'ONLINE'
        )
      })
      .catch(() => {
        props.handleFormAdd(
          {
            formName: formName,
            formData: data
          },
          'OFFLINE'
        )
      })
  }

  const classes = useStyles()
  const { map } = useLeaflet();

  const [anchorEl, setAnchorEl] = React.useState(null)

  const dispatch = useDispatch();

  const layerRef = useRef(L.featureGroup());

  const handleClick = event => {
    layerRef.current.clearLayers()
    setAnchorEl(event.currentTarget)
    dispatch(change(formName, "latitude", map.getCenter().lat));
    dispatch(change(formName, "longitude", map.getCenter().lng));
    L.circle(
      [map.getCenter().lat, map.getCenter().lng],
      radius, // this is where I am trying to use the value for 'radius'
      {
        weight: 1,
        color: "blue",
        fillColor: "blue",
        fillOpacity: 0.2
      }).addTo(layerRef.current);
    layerRef.current.addTo(map);
  }

  const handleClose = () => {
    layerRef.current.clearLayers()
    reset()
    setAnchorEl(null)
  }

  const open = Boolean(anchorEl)

  return (
    <Fragment>
      <MapButton
        title={'Add an area circle'}
        onClick={handleClick}
        right
        bottom={148}
      >
        <AdjustIcon
          fontSize="small"
        />
      </MapButton>
      <Popover
        className={classes.legend}
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'top',
          horizontal: 'left'
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center'
        }}
      >
        <Grid
          className={classes.list}
          container
          direction="column"
          justify="flex-start"
          alignItems="center"
        >
          <Grid item>
            <Typography variant="body2" align="center" gutterBottom>
              Add Area Marker
        </Typography>
          </Grid>
          <form onSubmit={handleSubmit(onSubmit)}>
            <Field
              name="radius"
              label="Radius"
              type="number"
              component={RenderTextField}
            />
            Radius: {radius}  // trying to render the value here
            <Field
              name="description"
              label="Description"
              type="text"
              component={RenderTextField}
            />
            <Button variant="container" type="submit" disabled={pristine || submitting}>Save</Button>
            <Button type="button" disabled={pristine || submitting} onClick={handleClose}>Cancel</Button>
          </form>
        </Grid>
      </Popover>
    </Fragment>
  );
}


const selector = formValueSelector(formName)


const mapStateToProps = ({
  firebase: { auth },
  network: { status },
  state
}) => ({
  _userUID: auth.uid,
  _authorName: auth.displayName,
  _status: status,
  radius: selector(state, 'radius')
})

export default compose(
  connect(
    mapStateToProps,
    { networkStatus, handleFormAdd }
  ),
  reduxForm({
    form: formName,
    destroyOnUnmount: true,
    forceUnregisterOnUnmount: true,
    enableReinitialize: true
  }),
  firestoreConnect()
)(withSnackbar(Circle))

Заранее благодарим за любые советы или решения

...