Bowis
Bowis

Reputation: 632

Use array of strings in React Hook Form

In a form that I am making the material that is being created in the form should have multiple width options that can be added. This means that I will have a text input where the user can add an option, and when this option is added, it should be added to the React Hook Form widthOptions array, without using the regular react state. How would one do this? How do you add an item to the total React Hook Form state, I only see options for just one input field corresponding to a property.

This is how i would do it using the regular React state

import { TrashIcon } from "@heroicons/react/24/outline";
import React, { useRef, useState } from "react";

const Test = () => {
  const [widthOptions, setWidthOptions] = useState<string[]>([]);
  const inputRef = useRef<HTMLInputElement>(null);
  const removeWidthOption = (widthOption: string) => {
    setWidthOptions(widthOptions.filter((option) => option !== widthOption));
  };

  const addWidthOption = (widthOption: string) => {
    setWidthOptions([...widthOptions, widthOption]);
  };

  const editWidthOptions = (widthOption: string, index: number) => {
    const newWidthOptions = [...widthOptions];
    newWidthOptions[index] = widthOption;
    setWidthOptions(newWidthOptions);
  };

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={() => addWidthOption(inputRef?.current?.value)}>
        Add Width Option
      </button>
      {widthOptions.map((option, index) => (
        <div className="flex">
          <input
            type="text"
            value={option}
            onChange={() => editWidthOptions(option, index)}
          />
          <button type="button" onClick={() => removeWidthOption(option)}>
            <TrashIcon className="w-5 h-5 mb-3 text-gray-500" />
          </button>
        </div>
      ))}
    </div>
  );
};

export default Test;

Upvotes: 0

Views: 3806

Answers (1)

Disco
Disco

Reputation: 1634

You can just the controller component for this as for all other fields. Since you have not shared any of you code here is a generic multi-select

<Controller
  name={name}
  render={({ field: { value, onChange, ref } }) => {
    return (
    // You can use whatever component you want here, the you get the value from the form and use onChange to update the value as you would with a regular state
      <Test
        widthOptions={value}
        setWidthOptions={onChange}
      />
    );
  }}
/>;

https://react-hook-form.com/api/usecontroller/controller/

And in you Test component remove the state and get the props instead

const Test = ({widthOptions, setWidthOptions}) => {
const inputRef = useRef<HTMLInputElement>(null);
.
.
.

Upvotes: 1

Related Questions