reactjs - 如何使用 .map 函数索引切换动态生成的下拉列表?
问题描述
我有一个数组,它为数组中的每个项目动态生成一个下拉列表。现在每个下拉列表共享相同的切换布尔值,因此它们都同时打开和关闭,我怎样才能使这个单独工作?
我将每个对象映射到此处的索引,然后开始创建下拉列表:
{Object.keys(props.totalWorkload.options).map((item, i) => (
<WorkloadOptions
key={i}
cnt={i}
appendChoiceList={props.appendChoiceList}
modalDropDown={props.modalDropDown}
toggleDropDown={props.toggleDropDown}
totalWorkloadOptions={props.totalWorkload.options[item]}
/>
))}
创建下拉选项组件时,我将索引传递给函数:
<div>
<Dropdown isOpen={props.modalDropDown} toggle={props.toggleDropDown.bind(props.cnt)}>
<DropdownToggle caret>{props.totalWorkloadOptions.optionTitle}</DropdownToggle>
<DropdownMenu>
{props.totalWorkloadOptions.options.map(op => (
// tslint:disable-next-line:no-invalid-this
// tslint:disable-next-line:jsx-no-lambda
<DropdownItem key={op} onClick= {() => props.appendChoiceList(props.totalWorkloadOptions.optionTitle, op)}>
{op}
</DropdownItem>
))}
</DropdownMenu>
<strong> {props.totalWorkloadOptions.optionDescription} </strong>
</Dropdown>
<br />
</div>
它将到达以下功能并控制台记录索引,然后将数组中的适当切换值设置为真/假:
toggleDropDown = (index: any) => {
console.log('triggered!:' + index);
let clicked = this.state.modalDropDownClicked;
// tslint:disable-next-line:no-conditional-assignment
if (clicked[index]=!clicked[index]){
this.setState({ modalDropDownClicked: !this.state.modalDropDown[index] });
}
};
解决方案
我可以推荐以下模式来切换动态创建的元素:
// Item.js
class Item extends React.Component {
handleClick = () => {
const { id, onClick } = this.props;
onClick(id);
}
render() {
const { isOpen } = this.props;
return (
<li><button onClick={this.handleClick}>{isOpen ? 'open' : 'closed'}</button></li>
)
}
}
// App.js
class App extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
const { items } = nextProps;
if (items !== prevState.prevPropsItems) {
return { items, prevPropsItems: items };
}
return null;
}
state = {
prevPropsItems: [],
items: []
}
toggleItem = id => this.setState(prevState => {
const items = prevState.items.map(item => {
if (item.id === id) {
return { ...item, isOpen: !item.isOpen }
} else {
return item;
}
});
return { items }
})
render(){
const { items } = this.state;
return (<ul>
{items.map(item => <Item key={item.id} id={item.id} onClick={this.toggleItem} isOpen={item.isOpen} />)}
</ul>);
}
}
// AppContainer.js
const itemsFromRedux = [
{ id: '1', isOpen: false },
{ id: '2', isOpen: false },
{ id: '3', isOpen: false },
]
ReactDOM.render(<App items={itemsFromRedux} />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.development.js"></script>
<div id="root"></div>
推荐阅读
- powershell - powershell 多列输出
- excel - 将列中的重复值计数制表到表格新工作表中
- c# - 为什么 CreationTime 与 LastWriteTime xamarin 相同?
- reactjs - 如何在 React useEffect 中正确清理?
- mysql - 为什么我在 Spring Boot 中对表数据执行更新查询后 MySQL View 返回旧数据?
- image - 加载资源失败:服务器响应状态为404()但访问url直接显示图片
- python - 为什么多处理比单核慢?使用 joblib 或 dask 会有所作为吗?
- bash - 使用 sed 命令将每个字母更改为字母表中的下一个
- jpa - Spring Data JPA @Query 不工作(findAll + filter 工作)
- python - Django AJAX:尝试在 POST 请求中传递列表时出错