React.js“不变违规:findComponentRoot”

时间:2015-01-05 09:39:57

标签: reactjs

我知道错误来自嵌套的东西和嵌套的_.map函数,但我无法弄清楚如何做到这一点。

在渲染函数的一部分下面:

我想做的是:

  1. 检查this.props.currencylist是否存在
  2. 然后显示<select>下拉列表
  3. 来自<options>
  4. this.props.currencylist

    { 
      this.props.currencylist ?
      <select  id="fiatselector" onChange={this.onSelectCurrency} value {this.props.selectedcurrency}>
      { 
         _.map(this.props.currencylist, function(currency) { 
           return <option value={currency}> {currency} </option>  
         })
      }
      </select>
      : 
      ""
    }    
    

    非常感谢!

    顺便说一句,在第一次渲染时它完美运行,当必须更新时出现错误,使用新的货币列表重新渲染会触发错误

2 个答案:

答案 0 :(得分:15)

这里的实际问题是价值周围的空间。

<option> {x} </option>

应该是:

<option>{x}</option>

前者最终呈现:

<option><span> </span>{x}<span> </span></option>

浏览器删除了span包装器,但React仍然期望它们在那里。

答案 1 :(得分:1)

我能够重现你的错误。显然,您需要将key属性添加到选项标记中。我希望我能提供更好的解释,但我不太了解ReactJs的解释。

以下是基于您的代码段的相关更改(此处仅更改是添加key属性。我只是在此处使用货币作为关键字):

_.map(this.props.currencylist, function(currency) {
     return <option key={currency} value={currency}> {currency} </option>
})

这是我用于测试的一个简单示例(略微修改渲染,但同样的想法):

var CurrentSelector = React.createClass({
    render: function() {
        var options = this.props.currencylist.map(function(currency) {
            return <option key={currency} value={currency}> {currency} </option>
        });
        if (this.props.currencylist) {
            return <div><select id="fiatselector">{options}</select></div>
        } else {
            return <div></div>
        }
    }
});

var App = React.createClass({
    getInitialState: function() {
        return {
            currencylist: [1,2,3],
            selectedcurrency: 1,
        }
    },
    render: function() {
        return (
            <div>
                <CurrentSelector
                    currencylist={this.state.currencylist}
                    selectedcurrency={this.state.selectedcurrency} />
                <button onClick={this.handleClick}>test</button>
            </div>
        );
    },
    handleClick: function() {
        this.setState({
            currencylist: [2, 3, 4, 5],
            selectedcurrency: 2,
        })
    }
});