当子组件是一个钩子时,Formik onChange处理程序不触发

时间:2019-08-26 23:14:50

标签: javascript reactjs formik

使用react + formik制作表单,并希望使用钩子来处理子组件状态。当我将挂钩的组件连接(哈哈)到我的表单时,formik onChange处理程序未按预期触发。

表格代码

... snip ...
  const classes = useStyles()
  return (
    <div>
      <FieldArray
        name='sessions'
        render={arrayHelpers => (
          <div>
            {values.sessions.map((data, i) => {
              return (
                <div className={classes.formControl} key={i}>
                  <TextField
                    margin='dense'
                    variant='outlined'
                    error={shouldShowError(
                      errors,
                      touched,
                      `sessions.${i}.name`
                    )}
                    style={{ display: 'flex', flex: 1 }}
                    value={values.sessions[i].name}
                    label={I18n.t('sessions.name.label')}
                    name={`sessions.${i}.name`}
                    onChange={handleChange}
                    onBlur={() => setFieldTouched(`sessions.${i}.name`)}
                  />
                  <DaysofWeek
                    value={values.sessions[i].days}
                    label={I18n.t('sessions.days.label')}
                    name={`sessions.${i}.days`}
                    onChange={handleChange}
                  />
... snip ...

当我将DaysOfWeek中的onChange行替换为{data =>console.log(data)}时,我会在控制台中看到期望的数据。

我还应该注意,这种形式的TextField组件可以正确更新formik。

作为参考,以下是DaysOfWeek组件代码:

import React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import FormControl from '@material-ui/core/FormControl'
import FormGroup from '@material-ui/core/FormGroup'
import FormControlLabel from '@material-ui/core/FormControlLabel'
import FormLabel from '@material-ui/core/FormLabel'
import Checkbox from '@material-ui/core/Checkbox'
import { symmetricDifference } from 'ramda'

const useStyles = makeStyles(theme => ({
  root: {
    display: 'flex'
  },
  formControl: {
    margin: theme.spacing(0)
  }
}))

export default function DaysofWeek ({ days = [], label = '', onChange }) {
  const classes = useStyles()
  const [stateDays, setState] = React.useState(days)

  const handleChange = value => _event => {
    let updatedDays = symmetricDifference([value], stateDays).sort()
    setState(updatedDays)
    onChange(updatedDays)
  }

  const staticDays = [
    [ 0, 'Sun' ],
    [ 1, 'Mon' ],
    [ 2, 'Tue' ],
    [ 3, 'Wed' ],
    [ 4, 'Thu' ],
    [ 5, 'Fri' ],
    [ 6, 'Sat' ]
  ]

  return (
    <div className={classes.root}>
      <FormControl component='fieldset' className={classes.formControl} >
        <FormLabel component="legend">{label}</FormLabel>
       { staticDays.map(([dayNum, dayLabel]) => 
        <FormGroup key={dayNum}>
          <FormControlLabel
            control={
              <Checkbox checked={stateDays.includes(dayNum)} onChange={handleChange(dayNum)} />
            }
            label={dayLabel}
          />
        </FormGroup>
       )}
      </FormControl>
    </div>
  )
}

package.json的相关位:

    "@material-ui/core": "^4.3",
    "@material-ui/icons": "^4.2",
    "@material-ui/pickers": "^3.2.4",
    "classnames": "^2.2.6",
    "date-fns": "^2.0.1",
    ....
    "formik": "2.0.1-rc.13",
     ....
    "react": "^16.8.6",
    "react-apollo": "^2.5.5",
    "react-dom": "^16.8.6",
    "react-icons": "^3.6.1",
.....

如何从Formik获取onChange以更新我的Formik状态?

1 个答案:

答案 0 :(得分:0)

实际的问题是Formik表单的DaysofWeek字段中的onChange处理程序。

我应该使用过来自formik的setFieldValue: onChange={data => setFieldValue(sessions.${i}.days, data)}