Reputation: 355
I am trying to get the value using the function getValues from react-hook-form from a child component that I have created (bear in mind this is an example and there is some logic of having created the component in this fashion). When I click on "Print Values" it doesn't get the value of authorId. Any ideas?
These are the two components:
const { register, control, getValues } = useForm();
<Button
onClick={() => {
console.log(getValues());
}}
>
Print Values
</Button>
<FormControl variant="outlined">
<InputLabel>Author</InputLabel>
<Controller
{...register}
control={control}
name="authorId"
render={({ field }) => (
<CustomDropdown control={control} category="Author" field={field} />
)}
/>
</FormControl>
CustomDropdown.js
const CustomDropdown = ({ field }) => {
const [selectedValues, setSelectedValues] = React.useState("");
<Select
{...field}
value={selectedValues || ""}
onChange={(e) => {
setSelectedValues(e.target.value);
}}
>
return <MenuItem key="1" value="1">
Option 1
</MenuItem>
<MenuItem key="2" value="2">
Option 2
</MenuItem>
</Select>;
};
Upvotes: 0
Views: 308
Reputation: 133
If you just need to output the value you should use the current scope
const CustomDropdown = () => {
const [selectedValues, setSelectedValues] = useState("value 1");
return (
<>
<button onClick={()=>console.log(selectedValues)}> Get value </button>
<select
value={selectedValues}
onChange={e => setSelectedValues(e.target.value)}>
<option value="value 1"> Value 1</option>
<option value="value 2"> Value 2</option>
<option value="value 3"> Value 3</option>
</select>
</>
)
}
If you need the value for other purposes use the Context Hook
Edit: Example of passing values from child to parent with the Context Hook. In your case you will need to define the useState
in App.js like this:
App.js
import { createContext, useState } from 'react';
import './App.css';
import Child from './Child.js'
export const MyContext = createContext("N0thing")
function App() {
const [getValue, changeValue] = useState(0)
return (
<div className="App">
<header className="App-header">
<MyContext.Provider value={{getValue, changeValue}}>
<Child/>
</MyContext.Provider>
Renderd by Parent {getValue}
</header>
</div>
);
}
export default App;
Child.js
import {useContext} from 'react'
import {MyContext} from './App.js'
const Child = () => {
const myContext = useContext(MyContext)
return (
<>
Renderd by Child {myContext.getValue}
<button onClick={()=>myContext.changeValue(myContext.getValue + 1)}> Change value from Child Componet </button>
</>
)
}
export default Child;
I hope I understand you correctly and that this can help.
Upvotes: 0
Reputation: 2783
There's a couple of things. First, the register
method needs to be called with the name of the input.
In the controller component you're not calling register
<Controller
{...register}
Instead change it to:
<Controller
{...register("authorId")}
Also you're not using the useForm
hook to control the value of the CustomDropdown
component.
Rather you're controlling the value using its own react state that the useForm
hook is unaware of
const [selectedValues, setSelectedValues] = React.useState("");
// ...
onChange={(e) => { setSelectedValues(e.target.value) }}
One solution is to pass the setValue
method and value
to the CustomDropdown
component as properties.
First file
const { register, control, getValues, setValue } = useForm();
const setAuthorIdValue = (value) => setValue("authorId", value);
<Button
onClick={() => {
console.log(getValues());
}}
>
Print Values
</Button>
<FormControl variant="outlined">
<InputLabel>Author</InputLabel>
<Controller
{...register("authorId")}
control={control}
name="authorId"
render={({ field }) => (
<CustomDropdown
control={control}
category="Author"
field={field}
value={getValues("authorId")}
setValue={setAuthorIdValue}
/>
)}
/>
</FormControl>
CustomDropdown.js
const CustomDropdown = ({ field, value, setValue }) => {
return <Select
{...field}
value={value || ""}
onChange={(e) => {
setValue(e.target.value);
}}
>
return <MenuItem key="1" value="1">
Option 1
</MenuItem>
<MenuItem key="2" value="2">
Option 2
</MenuItem>
</Select>;
};
Upvotes: 1