web-dev-qa-db-ja.com

React JS Error:反復不可能なインスタンスを非構造化しようとする無効な試み

オプションを設定する配列を取得する並べ替えフィルターがあります。オプションvalueが配列内のテキストに等しいことを確認しようとしていますが、タイトル内にエラーが表示されます。

Invalid attempt to destructure non-iterable instance

ユーザーがフィルターを更新したときに、ユーザーが行った選択に対して正しいテキストが表示されるように、テキストをオプションタグ内の値として渡す必要があります。

ここに私のコードがあります:

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

OnChangeとともに引数を渡していないので、見逃すことはよくあることですが、選択とオプションの組み合わせでは少しわかりにくいです。

次のようになります。

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"));

シンプルにするために、クラスとスタイルを削除しました。また、大文字のSelectとOptionを使用していたことに注意してください。これらは社内コンポーネントでカスタムでない限り、小文字にする必要があります。

注2selectの状態をどこかに保存する必要があるため、状態も導入しました-このコンポーネントの外部でselectボックスの状態を維持している場合、プロップ/コールバックの組み合わせを使用して、その値を1レベル高く維持することができます。

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

2
Chris

問題は変数iにあり、私はイベントobjectになります、使用i.target.valueユーザーが選択したvalueを取得するには、textを使用する代わりに、optionsの値としてindexを使用します。 、それは動作します、これを試してください:

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>
    )

これを確認してくださいfiddlehttps://jsfiddle.net/5pzcr0ef/

1
Mayank Shukla