J'ai un filtre de tri qui prend un tableau pour remplir les options. Essayer de voir l'option value
égale au texte dans le tableau mais j'obtiens l'erreur dans le titre:
Invalid attempt to destructure non-iterable instance
Je dois transmettre le texte en tant que valeur dans la balise d'option afin que, lorsque l'utilisateur met à jour le filtre, le texte correct s'affiche pour le choix que l'utilisateur a effectué.
Voici mon code:
function Sorting({by, order, rp}: SortingProps) {
const opts = [
['Price (low)', 'price', 'asc'],
['Price (high)', 'price', 'desc'],
['Discount (low)', 'discount', 'asc'],
['Discount (high)', 'discount', 'desc'],
['Most popular', 'arrival', 'latest'],
['Most recent', 'arrival', 'latest'],
];
const onChange = (i) => {
const [text, by, order] = opts[i];
refresh({so: {[by]: order}});
/* GA TRACKING */
ga('send', 'event', 'My Shop Sort By', text, 'Used');
};
return (
<div className={cn(shop.sorting, rp.sorting.fill && shop.sortingFill)}>
<Select className={shop.sortingSelect} label="Sort By" onChange={onChange} value={`${by}:${order}`}>
{opts.map(([text], i) =>
<Option key={i} value={text}>{text}</Option>
)}
</Select>
</div>
)
}
Vous ne passez pas un argument avec votre onChange, c’est une chose assez commune à rater - mais un peu moins évident avec une combinaison sélection/option.
Cela devrait ressembler à quelque chose comme:
class Sorting extends React.Component {
constructor(props) {
super(props);
this.opts = [
['Price (low)', 'price', 'asc'],
['Price (high)', 'price', 'desc'],
['Discount (low)', 'discount', 'asc'],
['Discount (high)', 'discount', 'desc'],
['Most popular', 'arrival', 'latest'],
['Most recent', 'arrival', 'latest'],
];
this.state = {
selected: 0, // default value
}
this.onChange = this.onChange.bind(this);
}
onChange(i) {
const [text, by, order] = opts[i.target.value];
};
render() {
return (
<div>
<select onChange={this.onChange} value={this.state.selected}>
{this.opts.map(([text], i) =>
<option key={i} value={i}>{text}</option>
)}
</select>
</div>
)
}
}
ReactDOM.render(<Sorting />, document.getElementById("a"));
Note J'ai supprimé vos classes et vos styles pour que cela reste simple. Notez également que vous utilisiez Sélection et Option en majuscule - sauf s’il s’agit de composants internes personnalisés, ils doivent être en minuscule.
Note2 J'ai également introduit state, car l'état de select doit être stocké quelque part - si vous conservez l'état de la zone de sélection en dehors de ce composant, vous pouvez évidemment utiliser une combinaison de props/callbacks pour conserver cette valeur un niveau plus élevé.
Le problème est avec la variable i
, je serai l'événement object
, utilisez i.target.value
pour obtenir le value
sélectionné par l'utilisateur, une dernière chose que vous avez utilisée text
en tant que valeur de options
, au lieu de cela, utilisez index
, cela fonctionnera :
const onChange = (i) => {
const [text, by, order] = opts[i.target.value];
refresh({so: {[by]: order}});
/* GA TRACKING */
ga('send', 'event', 'My Shop Sort By', text, 'Used');
};
return (
<div className={cn(shop.sorting, rp.sorting.fill && shop.sortingFill)}>
<select className={shop.sortingSelect} label="Sort By" onChange={onChange} value={`${by}:${order}`}>
{opts.map(([text], i) =>
<option key={i} value={i}>{text}</option>
)}
</select>
</div>
)
Cochez cette fiddle
: https://jsfiddle.net/5pzcr0ef/