我有一个下拉输入。单击输入旁边的向左或向右箭头按钮时,我想向前或向后移动当前选择的选项。单击下拉列表本身并选择一个选项时,它还应该跟踪该选项。
使用e.target.value(和控制台日志)单击时,我能够捕获当前所选对象的值,并且单击箭头按钮时,我能够增加或减少状态的计数(和控制台日志),但是我不确定将两者结合在一起的最佳方法(在数组中“ count”位置索引处显示项目?)
这是我的代码:
class DropdownMenu extends Component {
state = {
// Select options
options: [
{ name: 'Item 1', label: 'Item 1' },
{ name: 'Item 2', label: 'Item 2' },
{ name: 'Item 3', label: 'Item 3' },
{ name: 'Item 4', label: 'Item 4' },
{ name: 'Item 5', label: 'Item 5' }
],
value: 'select', // this should be the initial item ('Item 1')
count: 0
};
change = e => {
this.setState({ value: e.target.value }, console.log(this.state));
};
handleIncrement = () => {
this.setState(
{
count: this.state.count + 1
},
() => {
console.log(this.state);
}
);
};
handleDecrement = () => {
this.setState(
{
count: this.state.count - 1
},
() => {
console.log(this.state);
}
);
};
// Here I map over the options in state
dropdown = () => (
<div className="dropdown position-relative">
<select onChange={this.change} value={this.state.value}>
{this.state.options.map((option, index) => {
return (
<option key={index} name={option.name} value={option.name}>
{option.label}
</option>
);
})}
</select>
<div className="descend">
<img className="icon" src={descendIcon} alt="" />
</div>
</div>
);
// I want to use these arrows to increment or decrement the selection on the drop down
leftArrow = icon => (
<button
type="button"
className="btn btn-2"
onClick={this.handleIncrement}
>
<img className="icon" src={icon} alt="left arrow" />
</button>
);
rightArrow = icon => (
<button
type="button"
className="btn btn-2"
onClick={this.handleDecrement}
>
<img className="icon" src={icon} alt="" />
</button>
);
render() {
return (
<div className="flex flex-row">
<div className="flex-grow">{this.dropdown()}</div>
<div>
{this.leftArrow(leftIcon)}
{this.rightArrow(rightIcon)}
</div>
</div>
);
}
}
export default DropdownMenu;
答案 0 :(得分:1)
在此示例中,this.state.count
存储选定的options
索引。如果我们将this.state.count
设置为select
菜单的value
,那么当状态更新时,select
将重新呈现并显示与更新后的计数匹配的选项。
实时演示:https://codesandbox.io/s/38v727rrm
class DropdownMenu extends React.Component {
state = {
// Select options
options: [
{ name: 'Item 1', label: 'Item 1' },
{ name: 'Item 2', label: 'Item 2' },
{ name: 'Item 3', label: 'Item 3' },
{ name: 'Item 4', label: 'Item 4' },
{ name: 'Item 5', label: 'Item 5' }
],
count: 0
};
change = e => {
this.setState({ count: Number(e.target.value) });
};
handleIncrement = () => {
const c = this.state.count;
const len = this.state.options.length - 1;
let count = (c + 1 > len) ? c : c + 1;
this.setState({ count });
};
handleDecrement = () => {
const c = this.state.count;
let count = (c - 1 < 0) ? c : c - 1;
this.setState({ count });
};
dropdown = () => (
<div className="dropdown position-relative">
<select onChange={this.change} value={this.state.count}>
{this.state.options.map((option, index) => (
<option key={index} name={option.name} value={index}>
{option.label}
</option>
))}
</select>
<div className="descend">
<img className="icon" src="" alt="" />
</div>
</div>
);
leftArrow = icon => (
<button
type="button"
className="btn btn-2"
onClick={this.handleDecrement}
>
<img className="icon" src={icon} alt="left arrow" />
</button>
);
rightArrow = icon => (
<button
type="button"
className="btn btn-2"
onClick={this.handleIncrement}
>
<img className="icon" src={icon} alt="right arrow" />
</button>
);
render() {
return (
<div className="flex flex-row">
<div className="flex-grow">{this.dropdown()}</div>
<div>
{this.leftArrow('leftIcon')}
{this.rightArrow('rightIcon')}
</div>
</div>
);
}
}
答案 1 :(得分:0)
请勿同时在您的状态下存储count
和value
,因为这样您将有两个应选择的真实来源。只需存储count
,在您将得到value
的任何地方,都改为获取options[count]
。
答案 2 :(得分:0)
好,我想念您的问题,所以您可以使用约瑟夫(Joseph)描述的逻辑来做到这一点。 使用options [index]获取价值,并始终更新索引
答案 3 :(得分:-1)
看看React recommended way to handle setState。
由于React可以批处理setState来提高性能,所以您不能仅仅依靠this.state.count来作为更新状态的起点。相反,您需要调用传递prevState作为参数之一的setState,并使用prevState.count +1