控制器使用 React Select 提交未定义

Controller submitting undefined with React Select

我正在尝试将 React Select 与 useForm 一起使用,但在提交表单值时卡住了。

我的目标是使用默认值和 onChange 函数进行多值反应 select,以便在更改时进行一些验证(例如将 itens 的数量限制为 3)。

我已经尝试在其他帖子中搜索解决方案,并且确实对我的代码进行了一些更改,但遗憾的是我没有成功。

一切似乎都很完美,但是当我提交表单时,我的控制器产生了未定义的值。

import React, {useEffect, useState, useContext} from 'react'
import {useForm, Controller} from 'react-hook-form'
import axios from 'axios';
import Select from 'react-select';
import BeeUtils from '../../../utils/BeeUtils'

export default function EditCategory2({place, goBack}){
   var messageFieldRequired = 'Campo Obrigatório';
    
      const audienceOptions = [
        { value: 'Lésbicas', label: 'Lésbicas' },
        { value: 'Gays', label: 'Gays' },
        { value: 'Bissexuais', label: 'Bissexuais' },
        { value: 'Transexuais', label: 'Transexuais' },
        { value: 'Queer', label: 'Queer' },
        { value: 'Intersexo', label: 'Intersexo' },
        { value: 'Assexual', label: 'Assexual' },
        { value: 'Héteros', label: 'Héteros' },
        { value: 'Todxs', label: 'Todxs' }
      ]

    const handleAudienceSelector = (e) => {
        console.log('OK');    
        console.log(e);
        if(e.length > 3){
                e.pop();
                alert('max of 3 selected');
        }
    }
    
    
    const {register , handleSubmit, errors, setValue, getValues, setError, control} = useForm();

    
    const requestUpdate = async (data) => {
        data.createdBy = place.createdBy;
        data._id = place._id;
        data.recordUpdatedType = 'audience';
        console.log(data);
        return;
    }


    const selectRequired = (e) => {
        console.log(e);
        console.log('OK-2');
        //var error = e.length == 0? messageFieldRequired : '';
        //return error;
    }
    
    const onSubmit = data => {
            console.log(data)
            requestUpdate(data);
        }  
    
        return (
            <div className='cad-form'>
          <form onSubmit={handleSubmit(onSubmit)}> 
          <div className='cad-tit-container'> 
             <span className='cad-titulo'> Edit Here</span>
          </div>
          
          <div className='cad-container'>

            <label htmlFor='test-audience'>Audience</label>  
            <Controller
                    name="test-audience"
                    control={control}
                    rules={{ validate: selectRequired }}
                    render={() => (
                        <Select 
                            defaultValue={[audienceOptions[0], audienceOptions[1]]}
                            isMulti
                            onChange={handleAudienceSelector}
                            placeholder='Select Itens'
                            options={audienceOptions}
                            className="basic-multi-select selectCustom"
                            classNamePrefix="select"
                        />
                        )}
                />
            {errors?.targetAudience && <p>{errors.targetAudience.message}</p>}

          </div>

          <div className='btn-container'>
          <div className='cad-btn'><button onClick={(e) => goBack('initial')} className="btn waves-effect yellow darken-2">Voltar</button></div>
          <div className='cad-btn'><button type='submit' className="btn waves-effect yellow darken-2">Salvar Alterações</button></div>
          </div>
        </form>
        </div>
        )
    }

经过一些更改(感谢答案的帮助)我尝试了这段代码

import React, {useEffect, useState, useContext} from 'react'
import {useForm, Controller} from 'react-hook-form'
import axios from 'axios';
import Select from 'react-select';
import BeeUtils from '../../../utils/BeeUtils'

export default function EditCategory2({place, goBack}){
    var messageFieldRequired = 'Campo Obrigatório';
    
      const audienceOptions = [
        { value: 'Lésbicas', label: 'Lésbicas' },
        { value: 'Gays', label: 'Gays' },
        { value: 'Bissexuais', label: 'Bissexuais' },
        { value: 'Transexuais', label: 'Transexuais' },
        { value: 'Queer', label: 'Queer' },
        { value: 'Intersexo', label: 'Intersexo' },
        { value: 'Assexual', label: 'Assexual' },
        { value: 'Héteros', label: 'Héteros' },
        { value: 'Todxs', label: 'Todxs' }
      ]

    const handleAudienceSelector = (e) => {
        console.log('OK');    
        console.log(e);
        if(e.length > 3){
                e.pop();
                alert('max of 3 selected');
        }
    }
    
    
    const {register , handleSubmit, errors, setValue, getValues, setError, control} = useForm();

    
    const requestUpdate = async (data) => {
        data.createdBy = place.createdBy;
        data._id = place._id;
        data.recordUpdatedType = 'audience';
        console.log(data);
        return;
    }
    
    const onSubmit = data => {
            console.log(data)
            requestUpdate(data);
        }  
    
        return (
            <div className='cad-form'>
          <form onSubmit={handleSubmit(onSubmit)}> 
          <div className='cad-tit-container'> 
             <span className='cad-titulo'> Edit Here</span>
          </div>
          
          <div className='cad-container'>

            <label htmlFor='test-audience'>Audience</label>  
            <Controller
              name="targetAudience"
              control={control}
              defaultValue={[audienceOptions[0], audienceOptions[1]]}
              rules={{ required: messageFieldRequired }}
              render={({ field: { onChange, value } }) => (
                <Select
                  value={value}
                  onChange={onChange}
                  isMulti
                  placeholder="Select Itens"
                  options={audienceOptions}
                  className="basic-multi-select selectCustom"
                  classNamePrefix="select"
                />
              )}
            />

          </div>

          <div className='btn-container'>
          <div className='cad-btn'><button onClick={(e) => goBack('initial')} className="btn waves-effect yellow darken-2">Voltar</button></div>
          <div className='cad-btn'><button type='submit' className="btn waves-effect yellow darken-2">Salvar Alterações</button></div>
          </div>
        </form>
        </div>
        )
    }

但现在我得到了错误:TypeError: Cannot read 属性 'onChange' of undefined

它不起作用的原因是因为您忘记了通过 value 和 [=14] <Controller /> 组件与 <Select /> 组件=] 来自 <Controller />.

render prop 函数的属性
<Controller
  name="targetAudience"
  control={control}
  defaultValue={[audienceOptions[0], audienceOptions[1]]}
  rules={{ required: "Campo obrigatório", validate: isOnly3Values }}
  render={({ field: { onChange, value } }) => (
    <Select
      value={value}
      onChange={onChange}
      isMulti
      placeholder="Select Itens"
      options={audienceOptions}
      className="basic-multi-select selectCustom"
      classNamePrefix="select"
    />
  )}
/>

您也不需要在这里使用 useState 来处理错误状态,因为 RHF 已经提供了此功能。要设置必填字段,您只需设置验证对象的 required 属性,即可通过 rules 属性传递给 <Controller />。查看 here 了解有关 <Controller /> 的更多信息。我建议还使用 RHF 的 validate 函数来检查用户是否向您的 <Select /> 添加了超过 3 个项目并显示错误消息而不是使用警报。

我做了一些总体上的小改动并纠正了一些小问题(例如 errors 对象位于 formState 属性 中,因为 v7)。如果有什么不清楚的地方,请随时发表评论。