React-select defaultValue is not showing - reactjs

I'm using Formik and React-select library and defaultValue is not working/taking effect and it remains empty, i don't know why this is happening.
MySelectInput component:
interface Props {
// .. other props
options: CategoryOptions[];
defaultCategory: CategoryOptions;
}
const MySelectInput: React.FC<Props> = (props) => {
const [field, meta, helpers] = useField(props.name);
return (
<>
<Select
options={props.options}
isSearchable
defaultValue={props.defaultCategory}
onChange={(v) => helpers.setValue(v!.value)}
onBlur={() => helpers.setTouched(true)}
placeholder={props.placeholder}
styles={customSelectStyles}
/>
</>
)
};
export default MySelectInput;
Usage:
<MySelectInput
options={CategoryOptions}
placeholder="Category"
name="category"
label="Category"
defaultCategory={{ value: activity.category, label: activity.category }}
/>
My array of objects (CategoryOptions):
export const CategoryOptions: CategoryOptions[] = [
{ value: 'drinks', label: 'Drinks' },
{ value: 'music', label: 'Music' },
{ value: 'travel', label: 'Travel' },
];
The options are working and displaying well but defaultValue is not working. If i use static strings inside object properties like:
defaultCategory={{ value: "test", label: "test" }}
is working well. Any idea?

I think you should probably use an item from CategoryOptions.
Instead of
defaultValue={props.defaultCategory}
do
defaultValue={props.defaultCategory[0]}
I'm also wondering why your CategoryOptions object is same as the CategoryOptions type. Maybe you should rename it to categoryOptions

Related

Using MUI Autocorrect, with options populated by API

I almost have a working solution, but the label aspect is giving an undefined error, and I also want to make sure my solution is elegant as its a component I will reuse a lot.
I have an API which returns a json response, and for the purposes of this, the important values are; (I will stub out the API and just provide its response).
const countries =
[
{ country_id: 1, name: 'France', iso: 'fr'},
{ country_id: 2, name: 'Germany', iso: 'de'},
{ country_id: 3, name: 'United Kingdom', iso: 'gb'},
{ country_id: 4, name: 'Spain', iso: 'es'}
];
It's the MUI example with some tweaks to almost make it work as desired.
I want the label in the AutoComplete to be the country name, I want the value returned to be the country_id and the text in the AutoComplete to be the name of the Country they selected. It's the label that's not being set.
const Select = ({ country, onUpdate }) => {
//country is the valuable passed in to preselect an option or the option chosen, and the onUpdate is a function passed in (its a setState in the parent component).
const [countries, setCountries] = useState([]);
const [value, setValue] = React.useState('');
useEffect(() => {
api.get(`/countries`).then((response) => {
if (response.data) {
setCountries(response.data);
}
});
}, []);
return (
<>
<Autocomplete
autoHighlight
fullWidth
value={value}
options={countries}
onChange={(event, newValue) => {
setValue(newValue.name);
}}
inputValue={country}
onInputChange={(event, newInputValue) => {
onUpdate(newInputValue);
}}
renderOption={(props, country) => (
<Box component="li" {...props}>
{`{country.name} (${country.iso})`}
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
label="Choose a country"
/>
)}
/>
</>
);
};
Select.propTypes = {
country: PropTypes.string,
onUpdate: PropTypes.func.isRequired,
};
export default Select;
You need to add this line to your AutoComplete attributes:
getOptionLabel={(option) => option.name}
According to the documentation:
Options structure
By default, the component accepts the following options structures:
interface AutocompleteOption {
label: string;
}
// or
type AutocompleteOption = string;
for instance:
const options = [
{ label: 'The Godfather', id: 1 },
{ label: 'Pulp Fiction', id: 2 },
];
// or
const options = ['The Godfather', 'Pulp Fiction'];
However, you can use different structures by providing a getOptionLabel prop.
Another option is to change the name property in your response object into label and you will be set.

How can I update State in React using the React-Select Component and User Selection?

I'm trying to update a State in my project based on a User Selection from a dropdown menu.
I passed the 2 states (roomType & occupants) along with their setter/change functions (onRoomTypeChange & onOccupantsChange) from the parent Component.
I’ve tried to read through the React Select Library, but having trouble.
Wondering if someone could point me in the right direction.
import React from 'react';
import Select from 'react-select';
const roomOptions = [
{ value: 'Standard', label: 'Standard' },
{ value: 'Delux', label: 'Delux' }
];
const occupantOptions = [
{ value: 1, label: '1' },
{ value: 2, label: '2' },
{ value: 3, label: '3' },
{ value: 4, label: '4' },
];
const RoomDetails = (props) => {
let {
roomType,
onRoomTypeChange,
occupants,
onOccupantsChange
} = props;
const handleChange = (e) => {
onRoomTypeChange(e.target.value);
};
return (
<div>
<div className="form-group">
<label className="select-label">Room Type: {roomType} </label>
<Select
// value={e.target.value}
onChange={handleChange}
options={roomOptions}
theme={theme}
/>
<label className="select-label">Guests: {occupants}</label>
<Select
value={occupants}
onDatachange={onOccupantsChange}
options={occupantOptions}
theme={theme}
/>
</div >
</div>
);
};
export default RoomDetails;
I resolved the and wanted to post an update:
I had installed another package called “react-dropdown-select” that I removed from my package.json, I believe was interfering with my react-select package .
The return object was not an event, it was the selected object from the corresponding options array. I destructured the value property in the parameter and used the Setter Function on the value only.
I originally included a Value= attribute on the Select Component, which was set to my current state value
<Select
value={stateProperty}
/>
When I removed the Value attribute, the bug was gone
(Here is the solution)
import React from 'react';
import Select from 'react-select';
const roomOptions = [
{ value: 'Standard', label: 'Standard' },
{ value: 'Delux', label: 'Delux' }
];
const occupantOptions = [
{ value: 1, label: '1' },
{ value: 2, label: '2' },
{ value: 3, label: '3' },
{ value: 4, label: '4' },
];
const RoomDetails = (props) => {
let {
onRoomTypeChange,
onOccupantsChange
} = props;
const handleChangeRoom = ({ value }) => {
console.log(value);
onRoomTypeChange(value);
};
const handleChangeOccupants = ({ value }) => {
console.log(value);
onOccupantsChange(value);
};
return (
<div>
<div className="form-group mb-2">
<span className="form-label mt-3">Room Type </span>
<Select
onChange={handleChangeRoom}
options={roomOptions}
theme={theme}
placeholder="Room Type"
/>
<span className="form-label mt-3">Guests</span>
<Select
onChange={handleChangeOccupants}
options={occupantOptions}
theme={theme}
placeholder="Number of Guests"
/>
</div >
</div>
);
};
export default RoomDetails;

React-select fills an null value option when I try to update a created object

I'm using react-select for choosing members for a project based on a team list.
The format of the options is as specified in the docs (array of objects with label and value)
const options = [
{label: "Sam Altman", value: "61b5b1a4f401d574f5cefab7"},
{label: "Sam B", value: "87tgb1a4f401d574f5cefab7"},
{label: "John Altman", value: "9o2nb1a4f401d574f5sd347"},
]
The problem arises when I'm trying to update the values in a different view. The selected values contains null option (where I auto populate the form with the created values)
My current select component is as follows: -
<Select
isMulti
options={options}
value={item}
onChange={(newMembers) =>
setValues({ ...values, assignedTo: newMembers || [] })
}
/>
The problem only arises while updating the created members
use values instead of value. below is sample code.
import { useState } from 'react';
import Select from 'react-select';
const options = [
{ label: "Sam Altman", value: "61b5b1a4f401d574f5cefab7" },
{ label: "Sam B", value: "87tgb1a4f401d574f5cefab7" },
{ label: "John Altman", value: "9o2nb1a4f401d574f5sd347" }
];
function App() {
const [values, setVaues] = useState([]);
return (
<div>
<Select
isMulti
values={values}
onChange={(newMembers) => setVaues({ ...values, assignedTo: newMembers || [] })} options={options}
/>
</div>
);
}
export default App;

React combo doesnt select proper value

I'm totally new in react and I am trying to create add/edit form with combo box in it. I saved data in database but now when I loaded the form there is no selected value in "bank" combo. Looks like combo gets default value "Select" and I don't know where is the problem. My .net backend returns proper bank id from database and company.bankId also has value.
interface IProps {
closeAddEditCompanyModal: any,
cancelClick: any,
saveClick: any,
isVisible: boolean,
currentCompany: CompanyModel,
}
interface IState {
company: CompanyModel;
validationMessage: string,
isLoading: boolean,
activeIndex: number;
selectedIndex: number;
banks: Array<BankModel>;
isVisibleAddEditBankDialog: boolean;
}
handleChangeSelect = (key, e) => {
const company: CompanyModel = { ...this.state.company};
company[key] = e.value;
this.setState({ company: { ...company } });
};
<div style={{ minHeight: '50px' }}>
<FormControl>
<InputLabel htmlFor="active-label">Banks</InputLabel>
<Select
name="bankId"
options={this.state.banks.map( bank => ({
value: bank.bankId,
label: bank.bankName
}))}
onChange={(e) => this.handleChangeSelect('bankId', e)}
value={company && company.bankId ? company.bankId : ''}
>
</Select>
</FormControl>
import { useState } from "react";
import Select from "react-select";
function App() {
const [companyId, setCompanyId] = useState();
const letterChange = (data) => {
console.log(data);
company[data.value] = data.value;
// you can do here whatever you wish to do
// setCompanyId(data);
};
const banks = [
{ value: "bank1", label: "bank1" },
{ value: "bank2", label: "bank2" },
{ value: "bank3", label: "bank3" },
{ value: "bank4", label: "bank4" },
{ value: "bank5", label: "bank5" },
{ value: "bank6", label: "bank6" },
{ value: "bank7", label: "bank7" },
];
const company = [{
bank1: { value: "company1", label: "company1" },
bank2: { value: "company2", label: "company2" },
}];
return (
<>
<div className="App">
<Select
name="bankId"
options={banks}
onChange={letterChange}
value={companyId}
></Select>
</div>
</>
);
}
export default App;
I am still not clear what you are trying to achieve here. But here is a small piece of snippet that might help you.
Couple of things that i would like to point out in your code.
Inside your onChange handleChangeSelect you are passing a hardcoded value by passing bankId as string. I don't know if thats intentional.
You don't have to loop through the array inside options. Rather you can just pass the whole array itself.
This is just a suggestion but if you are already using material ui package you can use the select from material ui itself. This is just to avoid using extra packages unless and until there is a need for it.

How to display multiple selected values from a dropdown in React

I'm new to React and I wanted to create a dropdown which can select multiple values. For that I used the react-select plugin. In my React dev tool the selected values are getting stored but I'm not able to display all the selected values.
Any help is highly appreciated.
TIA
import React, { useState } from "react";
import Select from 'react-select'
const options = [
{ value: 'React', label: 'React' },
{ value: 'Vue', label: 'Vue' },
{ value: 'Angular', label: 'Angular' },
{ value: 'Java', label: 'Java' },
]
const [skills, setSkills] = useState([]);
const handleChange = (skill) => {
setSkills({skill})
console.log("skills", skill);
}
return (
<>
<h2>Please select all your skills</h2>
<form>
<Select
options={options}
onChange={handleChange}
isMulti={true}
value={value}
/>
<button>Next</button>
</form>
</>
)
}
export default UserSkills;
When I'm commenting isMulti prop, I'm getting that one selected value, but I'm not getting anything with isMulti prop.
You are controlling the Select component by giving it a value, and since you are not updating value in the handleChange function it will not be updated.
You could use the skills array as value instead and it will update as expected.
CodeSandbox
const options = [
{ value: "React", label: "React" },
{ value: "Vue", label: "Vue" },
{ value: "Angular", label: "Angular" },
{ value: "Java", label: "Java" }
];
function UserSkills() {
const [skills, setSkills] = useState([]);
const handleChange = (skills) => {
setSkills(skills || []);
};
return (
<>
<h2>Please select all your skills</h2>
<form>
<Select
options={options}
onChange={handleChange}
value={skills}
isMulti
/>
<button>Next</button>
</form>
</>
);
}
export default UserSkills;

Resources