React Hook Form Watch on Select Field - reactjs

I have trouble with the Select field.
When I use the watch on select HTML attribute and change options in it, it doesn't re-render in the console. it stays the same, but when I use onChange, its re-renders.
My example of code --->
const example = watch('skills')
console.log(watch('skills'))
console.log(example)
<select {...register( 'skills')}>
<option>1</option>
<option>2</option>
</select>
when I choose option 2, it doesn't show option 2. what should I do? thanks

React hook form does not work with select forms correctly (no optimization).

Try the following:
const watchShowAge = watch('primaryType');
...
{ watchShowAge === 10 && (<p>You are too young!</p>) }

Related

Can't get jest to recognize var value changed in onClick

I've got an Address react component which contains an address object defined by {streetAddress, additionalStreetAddress, city, jurisdiction, zipCode}.
Within the JSX I have jurisdiction as a dropdown Select of all the US states.
<Select
id={`${id}-jurisdiction`}
name="jurisdiction"
placeholderOption=" "
labelVisual="State"
value={jurisdiction}
>
{JURISDICTIONS.map((currentJurisdiction) => (
<SelectOption
id={`jurisdiction-${currentJurisdiction}`}
key={currentJurisdiction}
value={currentJurisdiction}
onClick={(e) => { jurisdiction = e.currentTarget.value; }}
>
{currentJurisdiction}
</SelectOption>
))}
</Select>
As you can see, onClick is setting address.jurisdiction to the selected option (i.e. the selected state).
In my test suite I am trying to test that this works by using the following test:
it('should update selected option and updated address jurisdiction when user makes a selection', async () => {
const jurisdictionDropDown = screen.getByRole('combobox');
const user = userEvent.setup();
const selectedJurisdiction = 'MA';
await user.selectOptions(jurisdictionDropDown, [selectedJurisdiction]);
expect(address.jurisdiction).toEqual('MA');
});
The issue I'm seeing is jest is expecting 'MA' but receiving an empty string. Is jurisdiction not being set, or am I referencing it wrong in the expect statement?
From the code, and the fact that you used the word "var" to describe your problem, it sounds like you are setting a normal variable rather than setting and keeping track of state.
Normally, in React you use state to keep track of values changing between renders, otherwise they get lost and you end up with the same initial values. You need to use the useState hook and use that to keep track of your state which hopefully will hopefully make the test pass (assuming it is written correctly).
import React, { useState } from 'react';
const [jurisdiction, setJurisdiction] = useState(JURISDICTIONS[0]);
<Select
id={`${id}-jurisdiction`}
name="jurisdiction"
placeholderOption=""
labelVisual="State"
value={jurisdiction}
>
{JURISDICTIONS.map((currentJurisdiction) => (
<SelectOption
id={`jurisdiction-${currentJurisdiction}`}
key={currentJurisdiction}
value={currentJurisdiction}
onClick={(e) => setJurisdiction(e.currentTarget.value)}
>
{currentJurisdiction}
</SelectOption>
))}
</Select>

How to set dropdown selection to localStorage?

I have a dropdown component where I am trying to set a localStorage value to the option that is selected from the dropdown.
const [userLanguage, setUserLanguage] = useState('en');
useEffect(() => {
localStorage.setItem("userLanguage", userLanguage ? userLanguage : '')
}, [userLanguage]);
return (
<select>
<option onClick={?}>one</option>
<option onClick={?}>two</option>
</select>
);
I am really confused on how to handle the onClick event that would set the selected option the the localStorage.
I have been able to find solutions that are somewhat related, but not that show examples for React, and specifically using hooks.
Any help would really be appreciated.
I would bind to the onChange event listener instead. The click event of option elements in single-select select elements is notoriously fragile. In your case, change your code to something like:
const [userLanguage, setUserLanguage] = useState('en');
useEffect(() => {
localStorage.setItem("userLanguage", userLanguage ? userLanguage : '')
}, [userLanguage]);
return (
<select onChange={(e) => setUserLanguage(e.target.value)}>
<option value="one">one</option>
<option value="two">two</option>
</select>
);
I added value attributes to your options only in an abundance of caution; by default the value of the select will gain the text of the option if the value is not explicitly set.
I should point out that older questions have pointed out the fragility of the click event on option elements. In particular, the answers to the question getting an onclick event to a select option using js by Vad.Gut explain the situation well.

Having a problem with PrimeReact Dropdown

I am still a novice in React Js and recently I have been developing using PrimeReact. The Forms and DataTables are doing well for me but I cant seem to figure out how deal with the Dropdown. My state is managed by redux and after mapStateToProps I and loading my data using componentDidMount I can console.log and see my data array. With a normal react select input I have been using the following code:
const {accounttypes} = this.props;
console.log(accounttypes)
let typesOptions = accounttypes.length > 0
&& accounttypes.map((item, index) => {
return (
<option key={item.id } value={item.id}>{item.name}</option>
)
}, this);
This works as an option as I can post to my backend. However I would want to use PrimeReact for all my forms and I have been struggling on how to go about it. The following has been my attempt and its giving me a headache:
<div className="p-field p-col-12 p-md-4">
<Dropdown
value={account_type}
optionValue = {accounttypes.id}
optionLabel = {accounttypes.name}
options={accounttypes}
onChange={this.onTypeChange}
placeholder="Select an Acco"
autoFocus = {true}
editable={true}
/>
</div>
account_type is the name of my field and my django model references the accountytpe model and would like to capture account_type whilst creating an Account. May someone help. And thanks in advance
optionLabel and optionValue should point to equivalent properties of your object. In your case I guess the correct way is this
optionValue="id"
optionLabel="name"

how to get selected value onChange of react redux-form drop down

I am using react redux form Fields and I have drop down of classes. I am able to select any class from drop down.
but the issue is that whenever I select any value (class) from drop down I want to trigger action onChange. When I trigger action with on change drop down values does not set and it does not show selected value.
I am using following lines of code
<Field name="class._id" component="select" className="form-control" onChange={this.onChange.bind(this)} >
<option value="">Select class...</option>
{this.props.classes.map(Class =>
<option value={Class._id} key={Class._id} >{Class.name}</option>)}
</Field>
here is onChange function
onChange(){
console.log(" Triggered")
}
If I do not set onChange event my drop down works correctly and it shows selected value correctly with proper text.
but I want to call function whenever use select any value
Can you give more context for this code, perhaps putting the whole component (and any modules or containers or whatever) in a JSBin or Fiddle? That will help SO posters better know how to help you. That said, it looks like your code is correct. You can get the value out of the select kind of like this:
onChange(event) {
console.log(event.target.value);
}
Does that help?
May be you should better use fields prop of redux and standard html elements?
const {fields} = this.props
<select {...fields.class} onChange={this.handleChange}>
...
handleChange(event) {
// do your stuff
this.props.fields.class.onChange(event)
}

Render selected item outside of input box for multi select of react-select library

How can we display the selected value just below the input box.
Use Case:
We are using multiple select of react-select , when we select the value from the select box , it comes inside the input box as selected. Can we have a method or something to get the selected values outside the input box (just below it)
Thanks in Advance!
I had a similar problem and I solved it creating a wrapper of react-select component and adding a state to my custom component. When the react-select changes I added the selected items to my component state and I show the in a custom div below, there you can add the styles that you want. Here an example of my approach: https://codesandbox.io/s/2kyy4998y
Hope this helps you.
Regards
I recently had to do this for a project I'm working on and wrote up how I did it here. The gist is that you need a wrapper component
// SelectWrapper.js
import ReactSelect from 'react-select'
const SelectWrapper = (props) => {
const { isMulti, value } = props;
return (
<div>
{isMulti ? value.map((val) => <span>{val.label}</span>) : null}
<Select {...props} controlShouldRenderValue={!isMulti} />
</div>
)
}
The very important part here is the controlShouldRenderValue prop which we disable when isMulti is true so the select dosn't show any selected values instead letting us take care of that

Resources