Francis
Francis

Reputation: 857

Using react-hook-form, how to programmatically modify values of inputs , depending on a selection?

Sounds simple, but I couldn't find a hello-world example of this, despite the richness of the doc. The closest I could find was in https://react-hook-form.com/advanced-usage, in the Working with virtualized lists section, but that relies on another module react-window, which introduces further complexity.

I want to allow the admin user to create-update-delete a list of products, with various properties.

My current code in JSX looks like this, I'd like to take advantage of error handling etc from react-hook-form:

    <ol >
      {products.map((row, index) => (
            <li 
                className={index === selectedProductIndex ? "selected" : ""} 
                key={index} 
                id={index} onClick={handleSelectProduct}>
                {row.name}
            </li>
        ))}
    </ol>
    <form onSubmit={handleSaveProduct}>
           <p>Product name: </p>
              <input name="productName" type="text" value={selectedProductName} 
              onChange={handleEdit_name} />
               (... more properties to edit here)
                    
                  </form>

The handlers save the values of selectedProductName, selectedProductIndex, etc in useState, in a database via axios, etc. I'm handling the values of each field individually in the useState, which I'm aware is laborious and heavy-handed.

Upvotes: 13

Views: 32608

Answers (1)

Francis
Francis

Reputation: 857

Well the answer was quite simple, although it took me a while to figure it out. In most of the examples, the onChange or onClick handlers don't use the event object, but nothing prevents you from adding it in. Then there's the setValue function to set the other control's value. Here's the code of a hello-world example. It offers one dropdown and one input field, the input field updates to match the selected value of the dropdown.

import React from "react";
import {useForm} from "react-hook-form";

function Test() {
    const {register, handleSubmit, errors, setValue} = useForm();
    const mySubmit = data => {
        console.log(data);
    }

    return (
        <div>
            <form onSubmit={handleSubmit(mySubmit)} className="reacthookform">
                <select name="dropdown" ref={register}
                        onChange={(ev) => setValue("productName", ev.target.value)}>
                    {["AAA", "BBB", "CCC"].map(value => (
                        <option key={value} value={value}>
                            {value}
                        </option>
                    ))}
                </select>
                <input name="productName" defaultValue="AAA" ref={register({required: true})} className="big"/>
                {errors.productName && <p className="errorMessage">This field is required</p>}
                <input type="submit" value="Save product"/>
            </form>
        </div>
    );
}

export default Test;

Upvotes: 20

Related Questions