I have this drop-down (select) component named Size as a child component and nested useFieldArray in the parent component I am receiving warnings every time I submit it and no values are being displayed in the console. What is happening and how can I fix this?
These are the errors:
Warning: Size:
refis not a prop. Trying to access it will result inundefinedbeing returned. If you need to access the same value within the child component, you should pass it as a different prop.Field is missing
nameattribute …
Link to codesandbox: https://codesandbox.io/s/react-hook-form-usefieldarray-nested-arrays-forked-vjwbp?file=/src/Drop_drowns/Size.js
Size.js
import { InputLabel, MenuItem, FormControl, Select } from "@mui/material";
const Size = ({ name, ref, defaultValue }) => {
return (
<FormControl fullWidth variant="filled">
<InputLabel id="Size Label">Size</InputLabel>
<Select
labelId="Size"
id="size"
name={name}
label="Product"
ref={ref}
defaultValue={defaultValue}
>
<MenuItem value="S">Small</MenuItem>
<MenuItem value="M">Medium</MenuItem>
<MenuItem value="L">Large</MenuItem>
</Select>
</FormControl>
);
};
export default Size;
Nested Field Array:
import React from "react";
import { useFieldArray } from "react-hook-form";
import Size from "./Drop_drowns/Size";
import { TextField } from "@mui/material";
export default ({ nestIndex, control, register }) => {
const { fields, remove, append } = useFieldArray({
control,
name: `test[${nestIndex}].nestedArray`
});
return (
<div>
{fields.map((item, k) => {
return (
<div key={item.id} style={{ marginLeft: 20 }}>
<label>Colors:</label>
<Size
name={`test[${nestIndex}].nestedArray[${k}].field1`}
ref={register({ required: true })}
defaultValue={item.field1}
style={{ marginRight: "25px" }}
/>
{/* <input
name={`test[${nestIndex}].nestedArray[${k}].field1`}
ref={register({ required: true })}
defaultValue={item.field1}
style={{ marginRight: "25px" }}
/> */}
<TextField
name={`test[${nestIndex}].nestedArray[${k}].field2`}
ref={register()}
defaultValue={item.field2}
/>
<TextField
name={`test[${nestIndex}].nestedArray[${k}].field3`}
ref={register()}
defaultValue={item.field3}
/>
<button type="button" onClick={() => remove(k)}>
Delete Colors
</button>
</div>
);
})}
<button
type="button"
onClick={() =>
append({
field1: "field1",
field2: "field2"
})
}
>
Add Colors
</button>
<hr />
</div>
);
};
fieldArray:
import React from "react";
import { useFieldArray } from "react-hook-form";
import NestedArray from "./nestedFieldArray";
import { TextField } from "@mui/material";
let renderCount = 0;
export default function Fields({ control, register, setValue, getValues }) {
const { fields, append, remove, prepends } = useFieldArray({
control,
name: "test"
});
renderCount ;
return (
<>
<ul>
{fields.map((item, index) => {
return (
<li key={item.id}>
<TextField
name={`test[${index}].name`}
ref={register()}
defaultValue={item.name}
/>
<button type="button" onClick={() => remove(index)}>
Delete
</button>
<NestedArray nestIndex={index} {...{ control, register }} />
</li>
);
})}
</ul>
<section>
<button
type="button"
onClick={() => {
append({ name: "append" });
}}
>
Add product
</button>
{/* <button
type="button"
onClick={() => {
setValue("test", [
...getValues().test,
{
name: "append",
nestedArray: [{ field1: "append", field2: "append" }]
}
]);
}}
>
update product
</button> */}
</section>
<span className="counter">Render Count: {renderCount}</span>
</>
);
}
index.js
import React from "react";
import { useForm } from "react-hook-form";
import FieldArray from "./fieldArray";
import ReactDOM from "react-dom";
import "./styles.css";
const defaultValues = {
test: [
{
product: "",
nestedArray: [{ field1: "", field2: "", field3: "" }]
},
{
product: "",
nestedArray: [{ field1: "", field2: "", field3: "" }]
}
]
};
function App() {
const {
control,
register,
handleSubmit,
getValues,
errors,
reset,
setValue
} = useForm({
defaultValues
});
const onSubmit = (data) => console.log("data", data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<h1>Array of Array Fields</h1>
<p>
The following example demonstrate the ability of building nested array
fields.
</p>
<FieldArray
{...{ control, register, defaultValues, getValues, setValue, errors }}
/>
<button type="button" onClick={() => reset(defaultValues)}>
Reset
</button>
<input type="submit" />
</form>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
CodePudding user response:
You are attempting to pass a prop called ref to a functional component. You can't pass refs to functional components. Also, what you're trying to pass isn't a ref. See https://reactjs.org/docs/refs-and-the-dom.html#adding-a-ref-to-a-dom-element for an example of what I'm talking about. If you rename the prop ref to reference, referral, referenceMaterial, etc, you will get rid of the issue. The following error in your console on the sandbox will let you know this as well.
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Just change your props to a different, more descriptive name and you'll be in business again.
