1

我一直在从 React Hook 表单的控制器中自定义 Material UI 自动完成,作为更大表单的一部分,但有一些困难。

下拉列表列出了从数据库中提取的建议(props.items,此处表示为对象),如果建议不存在,则可以选择使用下拉列表中的按钮以单独的形式添加新建议。这个“secondComponent”是通过条件渲染打开的。

当它被传递到第二个表单时,数据存储在状态 (heldData) 中,然后通过 React Hook Form 的重置传递回表单,这里为 reset(heldData)。

这完美地更新了表单的值,因为我有一个 onChange 事件,它根据传入的内容设置值。React Hook Form 通过重置处理该逻辑并将完整对象提供给 onChange。

但是,我还想设置 InputValue 以便填充 TextField。

为了在没有选项时创建一个动态按钮('Add ....(input)... as a guest'),我将输入的内容存储为“文本”。我认为我可以使用 OnChange 事件来使用相同的状态来更新 inputValue,如下所示。但是,当我从 onChange 设置文本时,更改不会反映在 inputValue 中。

也许这是因为 useState 是异步的,因此它不会在其他东西完全阻止它之前更新状态。如果是这样,它比我包含的其他代码要简单得多,但不确定。我已经排除了大部分表格(超过 500 行代码),但试图保留任何可能合适的部分。我希望我没有删除任何相关的内容,但如有必要可以更新。

道歉。这是我关于 Stack Overflow 的第一个问题,我对 React(和编码)还很陌生,而且代码可能一团糟。谢谢

 **Form** 

import React, { useState, useEffect} from "react";
import AutoCompleteSuggestion from "../general/form/AutoCompleteSuggestion";
import SecondComponent from './SecondComponent'
import { useForm } from "react-hook-form";

const items = {
  id: 2,
  name: "Mr Anderson"
}
   
const items2 = {
  id: 4,
  name: "Mr Frog"
}

const defaultValues = {
  guest: 'null',
  contact: 'null',
}

const AddBooking = () => {

  const { handleSubmit, register, control, reset, getValues} = useForm({
    defaultValues: defaultValues,
  });

  const [secondComponent, setSecondComponent] = useState(false);
  const [heldData, setHeldData] = useState(null)


  const openSecondComponent = (name) => {
    setSecondComponent(true)
    const data = getValues();
    setHeldData(data);
  }

  useEffect(() => {
    !secondComponent.open? 
    reset(heldData):''
  }, [heldData]);

  const onSubmit = (data) => {
    console.log(data)
  };

  return (
    <>

      {!secondComponent.open &&

        <form onSubmit={handleSubmit(onSubmit)}
          <AutoCompleteSuggestion
            control={control}
            name="guest"
            selection="id"
            label="name" 
            items={items}
            openSecondComponent={openSecondComponent}
          />

          <AutoCompleteSuggestion
            control={control}
            name="contact"
            selection="id"
            label="name"
            items={items2}
            openSecondComponent={openSecondComponent}
          />

        </form>
     };

      {secondComponent.open?
        <SecondComponent/>: ''
      };
    </>
  );
};

这是自定义的自动完成:

**AutoComplete**

import React, { useState } from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete,  from "@material-ui/lab/Autocomplete";
import parse from "autosuggest-highlight/parse";
import match from "autosuggest-highlight/match";
import { Controller } from "react-hook-form";
import Button from "@material-ui/core/Button";


const AutoCompleteSuggestion = (props) => {

  const [texts, setTexts] = useState('');
  
  return (
    
    <>
      <Controller
        name={props.name}
        control={props.control}
        render={({ onChange }) => (
          <Autocomplete
            options={props.items}
            inputValue={texts}  //NOT GETTING UPDATED BY STATE
            debug={true}
            getOptionLabel={(value) => value[props.label]}
            noOptionsText = {
              <Button onClick={()=> props.opensSecondComponent()}>
                Add {texts} as a {props.implementation}
              </Button>}
            onChange={(e, data) => {
              if (data==null){
                onChange(null)
              } else {
                onChange(data[props.selection]); //THIS ONCHANGE WORKS
                setTexts(data[props.label]) //THIS DOESN'T UPDATE STATE
              }}
            renderInput={(params) => (
              <TextField
                {...params}
                onChange = { e=> setTexts(e.target.value)}
              /> 
            )}
            renderOption={(option, { inputValue }) => {
              const matches = match(option[props.label1, inputValue);
              const parts = parse(option[props.label], matches);

              return (
                <div>
                  {parts.map((part, index) => (
                    <span
                      key={index}
                      style={{ fontWeight: part.highlight ? 700 : 400 }}
                    >
                      {part.text}
                    </span>
                  ))}
                </div>
              );
            }}
          />
        )}
      />
    </>
  );
};

export default AutoCompleteSuggestion;
4

0 回答 0