Reputation: 1646
In a React project using antd library, I've created a list of options from a json data which is populated as a drop-down list. Following is the code for reference
The json data
const newData = [
{
id: 123,
name: "Vijay"
},
{
id: 345,
name: "Sanket"
},
{
id: 546,
name: "Hitesh"
},
{
id: 789,
name: "Sameer"
},
{
id: 421,
name: "Akshay"
}
];
That data is used over here in <Select/>
<h2>Data 1</h2>
<Select
onChange={(key, val) => handleOnValuesChange(key, val)}
placeholder="Select any one"
style={{ width: 120 }}
options={newData.map((_) => ({
label: _.name,
value: _.id
}))}
bordered={false}
/>
<br />
<h2>Data 2</h2>
<Select
onChange={(key, val) => handleOnValuesChange(key, val)}
placeholder="Select any one"
style={{ width: 120 }}
options={newData.map((_) => ({
label: _.name,
value: _.id
}))}
bordered={false}
/>
The onChange function
const handleOnValuesChange = (key, val) => {
const allData = newData.map((data) => {
if (data.id === val) {
return {
...data,
disabled: true
};
} else {
return {
...data,
disabled: false
};
}
});
console.log("NEW DATA", allData);
};
When Vijay and Akshay is selected, I'am expecting the data as
0: {id: 1, value: "Vijay", disabled: true }
1: {id: 2, value: "Sanket", disabled: false}
2: {id: 3, value: "Hitesh", disabled: false }
3: {id: 4, value: "Sameer", disabled: false }
4: {id: 5, value: "Akshay", disabled: true }
but getting output as
0: {id: 1, value: "Vijay", disabled: false } {/* This disabled should change to true */}
1: {id: 2, value: "Sanket", disabled: false}
2: {id: 3, value: "Hitesh", disabled: false }
3: {id: 4, value: "Sameer", disabled: false }
4: {id: 5, value: "Akshay", disabled: true }
How to tackle this? Any appropriate solution highly appreciated
This is the codesandbox link as: https://codesandbox.io/s/bordered-less-antd-4-17-0-alpha-7-forked-wtur0
Upvotes: 1
Views: 1527
Reputation: 91
The newData should be stored in a state inorder to achieve disabling of options already selected. This is because the DOM gets re-rendered only if props or state is updated.
So in your code since the data is not stored in any state it does not change the non focused option, once the focused option is changed.
I have made some changes to the code and added the working example in sandbox.
const [data, setData] = React.useState(updatedData); //store the newData with disabled added
const [prevKey, setPrevKey] = React.useState(null); //store the last changed option
const handleOnValuesChange = (key, val) => {
const updating = [...data];
setPrevKey(val.value);
data.map((d, i) => {
if (d.id === val.value) {
updating[i] = {
...d,
disabled: true
};
}
if (d.id === prevKey) { //this toggles the previous selected value to false
updating[i] = {
...d,
disabled: false
};
}
});
setData(updating);
};
.....
<Select
onChange={(key, val) => handleOnValuesChange(key, val)}
placeholder="Select any one"
style={{ width: 120 }}
options={data
.filter((d) => d.disabled === false) //this shows only the options that are not disabled
.map((_) => {
console.log(_.name)
console.log(_.id)
return({
label: _.name,
value: _.id
})})}
Upvotes: 2
Reputation: 2672
I checked the sandbox code and found multiple issues with your code.
newData
value with update value otherwise it will old data for render.if (data.id === val.value)
instead of if (data.id === val)
in handleOnValuesChange function.You can check modified implementation on Sandbox
It will be great if you use the state for newData
Upvotes: 1
Reputation: 1036
you are always using the base newData element. so on each call of handleOnValuesChange you have no value set to disabled.
you need to update the newData or use some other temp variable.
also value is the first parameter for the onChange used by antd select.
let newData = [
{
id: 123,
name: "Vijay",
disabled: false,
},
{
id: 345,
name: "Sanket",
disabled: false,
},
{
id: 546,
name: "Hitesh",
disabled: false,
},
{
id: 789,
name: "Sameer",
disabled: false,
},
{
id: 421,
name: "Akshay",
disabled: false,
}
];
const handleOnValuesChange = (val) => {
console.log("VAL", val);
newData = newData.map((data) => {
console.log(data, val);
if (data.id === val) {
return {
...data,
disabled: true
};
}
return data;
});
console.log("NEW DATA", newData);
};
Upvotes: 1