首页 > 解决方案 > React-select:选定的选项不粘

问题描述

我是 React 的新手,需要一些帮助来看看我做错了什么:-(

我有一个组件,叫做 Bucket,每个桶可以有多个挑战,它是独立的组件,它看起来像这样, 在此处输入图像描述

代码的简化版本是这样的:

class CLL_Bucket extends Component {
   constructor(props) {
      super(props);
      this.state = {};
      this.state = {
         …
         bucketChallengesIdx: 0,       // to track the index of challegnes  
         bucketChallenges: this.props.bucket.bucketChallenges || [],
         …
      };

      …
      this.onBucketChallengeIDChanged = this.onBucketChallengeIDChanged.bind(this);
      …
   }

render() {
   const bucketIdx = this.props.idx;

   return (
      <div style={styles.container}>
         <div key={bucketIdx} className="row" style={styles.bucketStyle}>
            <div className="col-md-2">
               …
            </div>
            <div key={bucketIdx} className="col-md-4">
               <div>
                  …
               </div>
               <CLL_BucketChallengeDetail
                  challenges={this.props.challenges}
                  bucketChallengesIdx={this.state.bucketChallengesIdx}
                  bucketChallenges={this.state.bucketChallenges}
                  onBucketChallengeChanged={(challengeIdx, key, value) => this.onBucketChallengeChanged(challengeIdx, key,  value)}
/>
            </div>
            …
         </div>
      </div>
   );
}

class CLL_BucketChallengeDetail extends Component {

   constructor(props) {
      super(props);
      this.state = {
         bucketChallenges: this.props.bucketChallenges,
         bucketChallengeID: ""
      };

      this.onBucketChallengeIDChanged = this.onBucketChallengeIDChanged.bind(this);
      …
   }

   render() {
      return (
         <div className="col-md-4">
            <div>
               …
            </div>
            <table className="table table-bordered table-striped show">
               <thead>
               <tr>
                  <th>Challenge ID</th>
                  <th>Weight</th>
                  <th>Weight % Ratio</th>
                  <th>Action</th>
               </tr>
               </thead>
               <tbody>
               {this.props.bucketChallenges.map(this.renderChallengeDetail.bind(this))}
               </tbody>
            </table>
         </div>
      );
   }

   renderChallengeDetail(currentChallenge, index){

      const challengeIDOptions = this.props.challenges.map(data => {
         return {value: data.ID, label: data.ID}
      });
…

      return (
         <tr key={index}>
            <td className="col-xs-3 input-group-sm">
               <Select
                  options={challengeIDOptions}
                  defaultValue={challengeIDOptions[0]}
                  onChange={(option)=>this.onBucketChallengeIDChanged(index, option)}
                  isSearchable={true}
               />
            </td>
            …
         </tr>
      );
   }

   onBucketChallengeIDChanged(challengeIdx, option){

      var newChallengeList = this.state.bucketChallenges.map((item, j) => {
         if (j === challengeIdx) {
            // found the specific challenge in the list that needs to be updated
            item.ID = option.value;
         }
         return item;
      });

      this.setState({bucketChallenges:newChallengeList, bucketChallengeID:option.value},
         () => {console.log("HERE: "+ this.state.bucketChallengeID); this.props.onBucketChallengeChanged(challengeIdx, 'ID', option.value);});
   }
}

export default CLL_BucketChallengeDetail;

我遇到的问题是,在我更改挑战 ID 后,它确实显示在选择字段中,并且我可以从 React 开发人员工具中看到该值已更改,甚至 setState 也在其中设置了正确的值。 state.bucketChallengeID。但是,在我切换到我的应用程序的另一个选项卡并返回后,更改的选择字段将恢复为前一个。我究竟做错了什么???提前感谢帮助!

标签: javascripthtmlreactjsreact-select

解决方案


看起来您总是将默认值设置为defaultValue={challengeIDOptions[0]}. 因此,当您的组件加载时,它将重置为此默认值。如果每次切换选项卡时都会安装这些组件,则需要使用上下文或其他状态管理工具来保持状态。


推荐阅读