项目使用React Bootstrap https:/react-bootstrap.github.io。 应用程序从api接收到一个桶的列表。有两个选择下拉菜单。这里的目标是,在两个选择中不能选择同一个桶。因此,如果第一个选择中选择了 "Red "桶,那么第二个下拉列表中就不能有 "Red"。但是当第二个下拉列表重新显示时,在某些情况下,它显示的是错误的选择条目。
步骤如下
第一个列表[红,绿,蓝]。被选中。红色。第2个列表【绿、蓝】。被选中。绿色
第2个列表[红色,蓝色]。但所选的选项是蓝色的,应该是红色的,因为它是列表中第一个可用的。它应该是红色,因为它是列表中第一个可用的。
我明白这可能是因为红色之前不在第2个下拉列表中。但这不应该有关系吗?看到列表已经更新,组件已经重新渲染。
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
import ToBucket from "./toBucket";
class Buckets extends Component {
constructor(props) {
super(props);
this.state = {
fromBucketList: [],
toBucketList: [],
selectedFromBucket: [],
selectedToBucket: [],
};
}
handleFromBucketChange = (event) => {
let nam = event.target.name;
let bucketId = event.target.value;
const selectedFromBucket = this.getBucketById(bucketId);
let rebuiltToBucketList = [...this.state.fromBucketList];
let selectedFromBucketIndex = rebuiltToBucketList.indexOf(
selectedFromBucket
);
rebuiltToBucketList.splice(selectedFromBucketIndex, 1);
this.setState({ toBucketList: rebuiltToBucketList });
this.setState({ [nam]: selectedFromBucket });
this.setState({ selectedToBucket: rebuiltToBucketList[0] });
};
handleToBucketChange = (event) => {
let nam = event.target.name;
let bucketId = event.target.value;
const selectedToBucket = this.getBucketById(bucketId);
this.setState({ [nam]: selectedToBucket });
};
componentDidMount() {
const buckets = [
{ id: 1, color: "red" },
{ id: 2, color: "green" },
{ id: 3, color: "blue" },
];
let initialToBucketList = [...buckets];
initialToBucketList.splice(0, 1);
this.setState({ fromBucketList: buckets });
this.setState({ toBucketList: initialToBucketList });
this.setState({ selectedFromBucket: buckets[0] });
this.setState({ selectedToBucket: initialToBucketList[0] });
}
getBucketById = (id) => {
let foundedBucket = this.state.fromBucketList.find(
(element) => element.id == id
);
return foundedBucket;
};
render() {
return (
<React.Fragment>
<Form noValidate validated={this.state.validated}>
<Form.Group controlId="SelectFromBucket">
<Form.Label>Select FROM bucket:</Form.Label>
<Form.Control
required
type="text"
as="select"
onChange={this.handleFromBucketChange}
name="selectedFromBucket"
>
{this.state.fromBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
<React.Fragment>
<ToBucket
handleToBucketChange={this.handleToBucketChange}
toBucketList={this.state.toBucketList}
/>
</React.Fragment>
<p>
From :{this.state.selectedFromBucket.color}
<br></br>
To :{this.state.selectedToBucket.color}
</p>
</Form>
</React.Fragment>
);
}
}
export default Buckets;
第2个下拉列表。
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
class ToBucket extends Component {
render() {
return (
<React.Fragment>
<Form.Group controlId="SelectToBucket">
<Form.Label>Select TO bucket:</Form.Label>
<Form.Control
required
type="text"
as="select"
onChange={this.props.handleToBucketChange}
name="selectedToBucket"
>
{this.props.toBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
</React.Fragment>
);
}
}
export default ToBucket;
我更希望得到一个答案,它不是一个变通的方法,也不是一个黑客的代码,而是一个概念性的指导,如果这个方法不正确的话,它可以引导到另一个方向。
第二个下拉菜单的FormControl可能不会改变它的值,因为没有值道具传递给它。
试着将第一个桶中的选择值作为道具传递给第二个桶。
我从来没有使用过react-bootstrap,但这个代码段应该可以用。
第一个组件
<ToBucket
value={this.state.selectedToBucket && this.state.selectedToBucket.id}
handleToBucketChange={this.handleToBucketChange}
toBucketList={this.state.toBucketList}
/>
第二部分
import React, { Component } from "react";
import Form from "react-bootstrap/Form";
class ToBucket extends Component {
render() {
return (
<React.Fragment>
<Form.Group controlId="SelectToBucket">
<Form.Label>Select TO bucket:</Form.Label>
<Form.Control
required
value={this.props.value}
type="text"
as="select"
onChange={this.props.handleToBucketChange}
name="selectedToBucket"
>
{this.props.toBucketList.map((bucket) => (
<option key={bucket.id} value={bucket.id}>
{bucket.color}
</option>
))}
</Form.Control>
</Form.Group>
</React.Fragment>
);
}
}
export default ToBucket;