web-dev-qa-db-fra.com

Réaction de l'erreur JS: tentative non valide de destruction de l'instance non-itérable

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>
    )
}
9
Filth

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é. 

http://codepen.io/cjke/pen/egPKPB?editors=0010

2
Chris

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/

1
Mayank Shukla