Don't use selected Error using Material UI select component - reactjs

I am getting an error:
Warning: Use the defaultValue or value props on instead
of setting selected on .
<Select
onChange={props.changecompany}
value={props.currCompany != undefined ? props.currCompany.id : -1}
>
<option key={'empty'} value={'-1'}>
None
</option>
{mapstructure()}
</Select>;
And here is my mapstructure()
const mapstructure = () => {
return companies.map((company) => (
<option key={company.Id.toString()} value={company.Id}>
{company.Name}
</option>
));
};
I'm still learning so it is probably something fairly obvious, but the google solutions havent seemed to have fixed it. TIA

Here is what I think:
React throws a warning (not error) because, Material UI is using selected instead of value.
You have done nothing wrong and should not worry about it.
This can be fixed by Material UI itself in the upcoming updates if you raise this issue.
I hope this clears your doubt.

Related

Conditionally enabling a form button with react-hook-form and material ui

I'm creating a React form with Material UI. My goal is to force the user to answer all the questions before they can click the download button. In other words I'm trying to leave the download button in the disabled state until I can determine that values are set on each field. I've tried to get this working with and without react-hook-form.
What I've tried
Without react-hook-form...
I have my example in coding sandbox here:
https://codesandbox.io/s/enable-download-button-xwois4?file=/src/App.js
In this attempt I abandoned react-hook-form and added some logic that executes onChange. It looks through each of the formValues and ensures none of them are empty or set to "no answer". Like this:
const handleInputChange = (e) => {
// do setFormValues stuff first
// check that every question has been answered and enable / disable the download button
let disableDownload = false;
Object.values(formValues).forEach((val) => {
if (
typeof val === "undefined" ||
val === null ||
val === "no answer" ||
val === ""
) {
disableDownload = true;
}
});
setBtnDisabled(disableDownload);
The problem with this approach, as you'll see from playing with the UI in codesandbox, is that it requires an extra toggle of the form field value in order to detect that every field has been set. After the extra "toggle" the button does indeed re-enable. Maybe I could change this to onBlur but overall I feel like this approach isn't the right way to do it.
Using react-hook-form
With this approach...the approach I prefer to get working but really struggled with, I ran into several problems.
First the setup:
I removed the logic for setBtnDisabled() in the handleInputChange function.
I tried following the example on the react-hook-form website for material ui but in that example they're explicitly defining the defaultValues in useForm where-as mine come from useEffect. I want my initial values to come from my questionsObject so I don't think I want to get rid of useEffect.
I couldn't figure out what to do with {...field} as in the linked material ui example. I tried dropping it on RadioGroup
<Controller
name="RadioGroup"
control={control}
rules={{ required: true }}
render={({ field }) => (
<RadioGroup
questiontype={question.type}
name={questionId}
value={formValues[questionId]}
onChange={handleInputChange}
row
{...field}
>
but I get an MUI error of : MUI: A component is changing the uncontrolled value state of RadioGroup to be controlled.
Also, I don't see that useForm's state is changing at all. For example, I was hoping the list of touchedfields would increase as I clicked radio buttons but it isn't. I read that I should pass formState into useEffect() like this:
useEffect(() => {
const outputObj = {};
Object.keys(questionsObject).map(
(question) => (outputObj[question] = questionsObject[question].value)
);
setFormValues(outputObj);
}, [formState]);
but that makes me question what I need to do with formValues. Wondering if formState is supposed to replace useState for this.

React Hook Form Watch on Select Field

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>) }

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)
}

Resources