Reputation: 81
I have a select inside a ReactJs component, which contains some options, and I would like the selected option to be added to another select that is in another component. Example:
const conponent1 = () => {
return <>
<select>
<option value="">Select a option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<component2 />
</>
}
const component2 = () => {
return <>
<select>
<option value="">Select a option</option>\
//It does not contain any options because one has not yet been chosen in the previous select.
</select>
</>
}
The user selects option 2, so this option must be added to the select of the second component.
const conponent1 = () => {
return <>
<select>
<option value="">Select a option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option> // Chosen option.
<option value="3">Option 3</option>
</select>
<component2 />
</>
}
const component2 = () => {
return <>
<select>
<option value="">Select a option</option>\
<option value="2">Option 2</option> // It was added because it was the chosen option.
</select>
</>
}
Upvotes: 2
Views: 4809
Reputation: 2745
https://codesandbox.io/s/nice-cartwright-6zulx?file=/src/index.js:0-69
import { useState } from "react";
import "./styles.css";
const baseOptions = [
{
label: "option 1",
value: "1"
},
{
label: "option 2",
value: "2"
},
{
label: "option 3",
value: "3"
}
];
const Select = ({ options, onChange, value, disabledOptions = [] }) => (
<select onChange={onChange} value={value}>
<option disabled value="">
select an option
</option>
{options.map((option, i) => (
<option
key={option.value}
value={option.value}
disabled={
disabledOptions.findIndex((o) => o.value === option.value) !== -1
}
>
{option.label}
</option>
))}
</select>
);
export default function App() {
const [selectedOptions, setSelectedOptions] = useState([]);
const [firstSelectValue, setFirstSelectValue] = useState("");
const [secondSelectValue, setSecondSelectValue] = useState("");
const handleFirstSelectChange = (e) => {
const value = e.target.value;
const option = baseOptions.find((o) => o.value === value);
setSelectedOptions([...selectedOptions, option]);
setFirstSelectValue(option.value);
};
const handleSecondSelectChange = (e) => {
setSecondSelectValue(e.target.value);
};
return (
<div className="App">
<Select
options={baseOptions}
onChange={handleFirstSelectChange}
value={firstSelectValue}
disabledOptions={selectedOptions}
/>
<Select
options={selectedOptions}
onChange={handleSecondSelectChange}
value={secondSelectValue}
/>
<div>Selected Value: {secondSelectValue}</div>
</div>
);
}
Upvotes: 1
Reputation: 3339
You can do something like:
import React from "react";
const App = () => {
const [options, setOptions] = React.useState([]);
const Conponent2 = () => {
return(
<select>
<option value="-1">Select a option</option>
{
options.map(el => <option value={el.value}>{el.text}</option>)
}
</select>
)
};
const Conponent1 = ({onChange}) => {
return(
<>
<select onChange={onChange}>
<option value="-1">Select a option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<Conponent2 />
</>
)
};
const onChange = (e) => {
setOptions([{
value: e.target.value,
text: e.target.options[e.target.selectedIndex].text,
}])
}
return <Conponent1 onChange={onChange} />;
}
export default App;
And if you want to keep the prev selected options you can:
setOptions([...options, {
value: e.target.value,
text: e.target.options[e.target.selectedIndex].text,
}])
Upvotes: 0
Reputation: 1
If you use the exact same select, why don't you use the same component and add options with props? Something like onchange of first select setstate of selected option. Then give the state as props when you render the second select like this.state.map(option=>{option})
Upvotes: 0