react.js中的主要警告

时间:2018-10-18 15:29:41

标签: reactjs

我得到这个:

  

警告:数组或迭代器中的每个子代均应具有唯一的“键”道具。

这是我的下拉组件代码:

render() {
    let dropDownClasses = [classes["im-dropdown"], classes[this.state.size], classes[this.state.dropStyle], classes[this.status]];
    let itemcount = -1;
    let options;
    if(this.state.options !== undefined){
        options = this.state.options.map(option => {
            itemcount++;
            return(<div><li key ={'opt_'+this.state.name+'_'+itemcount}  role="option" aria-selected="false" value={option.value} tabIndex={itemcount} onClick={this.handleSelect.bind(this, this.state.name, option.value, option.text)}>  {option.text} </li></div>)
        });
    }

    return (
        <div className={dropDownClasses.join(' ')}>
            <button aria-haspopup="listbox" aria-expanded="false" onClick={this.handleOpen}>
                <span>{this.state.label}</span><span className={classes["caret"]}><i className="fa fa-angle-down"></i></span>
            </button>
            <ul className={classes["options"]} role="listbox" aria-labelledby={"im-drop_" +this.state.size+"_"+this.state.dropStyle} >
                <span key ={'opt_'+this.state.name+'_'+itemcount}>{options} </span>
            </ul>
        </div>
    );
}

我通过这样的另一个组件SideDrawer.js调用它:

    <div>
        <span className ={classes["filter"]}><strong>FILTER BY</strong></span>
    </div> 
    <Dropdown key={'opt_'+ clientDropdown.label} label={clientDropdown.label} name={clientDropdown.name} options={clientDropdown.options} action={props.formHandler}/>
    <Dropdown  label={typeDropdown.label} name={typeDropdown.name} options={typeDropdown.options} action={props.formHandler}/>
    <Dropdown  label={categoryDropdown.label} name={categoryDropdown.name} options={categoryDropdown.options} action={props.formHandler}/>
</div>

该警告似乎即将到来,因为我在一个div中多次调用了Dropdown组件(更像是一组项),从而导致了Key警告。我尝试使用“钥匙”作为道具,但不是_

4 个答案:

答案 0 :(得分:2)

  
      
  1. 不要直接在render中绑定函数,而总是在构造函数中绑定
  2.   
  3. 不要将li放入div
  4.   
  5. 尝试保持渲染部分尽可能干净
  6.   
  7. 您将键设置为li而不是div,这就是收到警告的原因
  8.   
  9. 同样,在执行循环时,需要将键设置为父jsx元素,并且键应来自唯一的数据。如果你   不要从数据中获得每个对象的唯一ID,然后使用索引作为键   像下面这样。请记住,索引始终是第二选择。
  10.   

我已尽可能简化了您的代码

constructor(props){
  super(props);
  this.handleSelect = this.handleSelect.bind(this);
}
render() {
    const { options, name, label, dropStyle, size } = this.state;
    const dropDownClasses = [classes["im-dropdown"], classes[size], classes[dropStyle], classes[this.status]];
    return (
        <div className={dropDownClasses.join(' ')}>
            <button aria-haspopup="listbox" aria-expanded="false" onClick={this.handleOpen}>
                <span>{label}</span><span className={classes["caret"]}><i className="fa fa-angle-down"></i></span>
            </button>
            <ul className={classes["options"]} role="listbox" aria-labelledby={"im-drop_" +size+"_"+dropStyle} >
                  {Array.isArray(options) && options.length && options.map((option, index) => (
                      <li key ={`Key_${index}`} role="option" aria-selected="false" value={option.value} tabIndex={index} onClick={() => this.handleSelect(name, option.value, option.text)}>  {option.text} </li>
                  ))}
            </ul>
        </div>
    );
}

答案 1 :(得分:1)

将键移到父div,也可能要删除键后的多余空间。您也可以使用索引参数代替项目计数。

    options = this.state.options.map((option, index) => {
        return(<div key={'opt_'+this.state.name+'_'+index}><li role="option" aria-selected="false" value={option.value} tabIndex={itemcount} onClick={this.handleSelect.bind(this, this.state.name, option.value, option.text)}>  {option.text} </li></div>)
    });

答案 2 :(得分:0)

在使用每个元素的地图函数唯一key迭代并返回任何html元素时,否则每个元素都将需要警告,因为节点元素安装在键上,但不是强制给出键,而是最佳性能和所需的零错误代码。

在您的代码中,您应该将键提供给父元素,因此,将键提供给子元素的映射功能不应视为map keys

您的代码:

if(this.state.options !== undefined){
        options = this.state.options.map(option => {
            itemcount++;
            return(<div><li key ={'opt_'+this.state.name+'_'+itemcount}  role="option" aria-selected="false" value={option.value} tabIndex={itemcount} onClick={this.handleSelect.bind(this, this.state.name, option.value, option.text)}>  {option.text} </li></div>)
        });
    }

修复代码:密钥应位于父元素中

if(this.state.options !== undefined){
        options = this.state.options.map(option => {
            itemcount++;
            return(<div key ={'opt_'+this.state.name+'_'+itemcount} ><li role="option" aria-selected="false" value={option.value} tabIndex={itemcount} onClick={this.handleSelect.bind(this, this.state.name, option.value, option.text)}>  {option.text} </li></div>)
        });
    }

答案 3 :(得分:0)

if(this.state.options !== undefined){
    options = this.state.options.map((option,i) => {
        itemcount++;
        return(<div key={i}><li   role="option" aria-selected="false" value={option.value} tabIndex={itemcount} onClick={this.handleSelect.bind(this, this.state.name, option.value, option.text)}>  {option.text} </li></div>)
    });
}

在数组中创建组件时,应在父组件中提供一个键,现在我将index设置为键..希望它将为您提供帮助