-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option elements shouldn't have keys, based on index #48
Conversation
Keys in options shouldn't depend on key index here : https://github.com/rkit/react-select2-wrapper/blob/master/src/components/Select2.js#L159 ```jsx /* This */ return (<option key={`option-${k}`} value={id} {...itemParams}>{text}</option>); /* should be changed to this: */ return (<option key={`option-${id}`} value={id} {...itemParams}>{text}</option>); ``` Otherwise it doesn't re-render options, when options list is changed.
@@ -156,7 +156,8 @@ export default class Select2 extends Component { | |||
makeOption(item, k) { | |||
if (this.isObject(item)) { | |||
const { id, text, ...itemParams } = item; | |||
return (<option key={`option-${k}`} value={id} {...itemParams}>{text}</option>); | |||
const sanitized_id = id + ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this is needed.
The key will be a string in any way…
Also we have to provide an ability use several options with same IDs, which is prohibited by react, but not strictly prohibited by select. so, best solution seems to be ```js const key = 'option-' + k + '-' + id; return (<option key={key} value={id} {...itemParams}>{text}</option>); ``` And about sanitizing: was not sure, if react could use _any_ string as a key. Had to [check](https://facebook.github.io/react/docs/reconciliation.html#keys) So now it seems to solve the problem
@@ -156,7 +156,8 @@ export default class Select2 extends Component { | |||
makeOption(item, k) { | |||
if (this.isObject(item)) { | |||
const { id, text, ...itemParams } = item; | |||
return (<option key={`option-${k}`} value={id} {...itemParams}>{text}</option>); | |||
const key = 'option-' + k + '-' + id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check js style
Is it better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is a "$k" in the key, the key will always be different. Isn't it?
No, i have a problem with this. And solved that exactly the way how it's described in PR. So i have async app, and it loads one list (of users) when it loads page, then it performs a request, and puts the response to select2. So list is changed. But react doesn't want to re-render list item, thinking that in child with key="2" nothing has changed. |
Sorry, but I still not understand you.
Yes, I also suggest to use https://facebook.github.io/react/docs/reconciliation.html
|
Indeed, but if you reorder the list in model - dropdown also should be re-rendered.
and totally based on model and desired representation, not on "unstable" values. |
So, do you think we don't need to re-render dropdown, if the order is changed? How reactjs will react on that, if we just add an element to the beginning? Will it re-draw everything properly ? |
The dropdown will be changed.
Yes, this code works right: // use only `id`
return (<option key={`option-${id}`} value={id} {...itemParams}>{text}</option>);
// initial state
this.state = {
data: [
{ text: 'bug', id: 1 },
{ text: 'feature', id: 2 },
{ text: 'documents', id: 3 },
],
};
// in render()
<Select2 data={this.state.data} />
<button onClick={() => this.setState({
data: [
{ text: 'bug', id: 1 },
{ text: 'documents', id: 3 },
{ text: 'feature', id: 2 },
],
})}
>
update
</button> if we also add an element to the beginning, it will re-render. Everything is fine. |
I think if we don't need to re-render all nodes of dropdown if order is changed and if your example works fine, we can leave |
that should work fine
I released a new version, thanks |
Wonderful) thanks) |
Keys in
<option/>
ekenebts shouldn't depend on key index here : https://github.com/rkit/react-select2-wrapper/blob/master/src/components/Select2.js#L159Otherwise it doesn't re-render options, when options list is changed.
Also, probably
<optgroup>
keys could have been made of their children's keys, but that seemed overhead to me.