オプションを設定する配列を取得する並べ替えフィルターがあります。オプション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>
)
}
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レベル高く維持することができます。
問題は変数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>
)
これを確認してくださいfiddle
: https://jsfiddle.net/5pzcr0ef/