警告:flattenChildren(…):遇到两个孩子

我看过同样的问题,但无法弄清楚我的错误在哪里。

我的实时搜索框效果很好但是一旦您删除了搜索查询(word),警告就会显示在反应控制台中:

警告:flattenChildren(…):遇到两个孩子用同一把钥匙, .$1 。 子键必须是唯一的; 当两个孩子共用一把钥匙时,只会使用第一个孩子。

这是我的整个jsx文件:

 var SearchBox = React.createClass(http://sofzh.miximages.com/javascript/{ doSearch:function()http://sofzh.miximages.com/javascript/{ // remove .getDOMNode() for newer version of reat-rails 1.4.x var query = (this.refs.searchInput.value).toLowerCase(); // this is the search text this.props.doSearch(query); }, render:function()http://sofzh.miximages.com/javascript/{ return  } }); var DisplayTable = React.createClass(http://sofzh.miximages.com/javascript/{ render:function()http://sofzh.miximages.com/javascript/{ //making the cards to display var cards=[]; var default_url = "/assets/profile_avatar/thumb/missing.png"; this.props.data.map(function(s) http://sofzh.miximages.com/javascript/{ cards.push(  
http://sofzh.miximages.com/javascript/{s.support_title}
Reward: http://sofzh.miximages.com/javascript/{s.reward_after_support}
http://sofzh.miximages.com/javascript/{s.remote_support == 'on' ? 'Remote / Anywhere' : s.city + ', '+ s.country}

http://sofzh.miximages.com/javascript/{s.profiles[0].first_name}
Applications: http://sofzh.miximages.com/javascript/{s.interest_recieved} | Posted: http://sofzh.miximages.com/javascript/{moment(s.created_at).fromNow()}
) }); //returning the card return(
http://sofzh.miximages.com/javascript/{cards}
); } }); var InstantBox = React.createClass(http://sofzh.miximages.com/javascript/{ doSearch:function(queryText)http://sofzh.miximages.com/javascript/{ //console.log(queryText) //get query result var queryResult=[]; this.props.data.map(function(s)http://sofzh.miximages.com/javascript/{ if(s.support_title.toLowerCase().indexOf(queryText)!=-1) http://sofzh.miximages.com/javascript/{ queryResult.push(s); } if (s.city != null) http://sofzh.miximages.com/javascript/{ if(s.city.toLowerCase().indexOf(queryText)!=-1) http://sofzh.miximages.com/javascript/{ queryResult.push(s); } } if (s.country != null) http://sofzh.miximages.com/javascript/{ if(s.country.toLowerCase().indexOf(queryText)!=-1) http://sofzh.miximages.com/javascript/{ queryResult.push(s); } } }); this.setState(http://sofzh.miximages.com/javascript/{ query:queryText, filteredData: queryResult }) }, getInitialState:function()http://sofzh.miximages.com/javascript/{ returnhttp://sofzh.miximages.com/javascript/{ query:'', filteredData: this.props.data } }, render:function()http://sofzh.miximages.com/javascript/{ return (
); } });

我真的没有看到问题。 我错过了什么吗?

代码中的怪癖是indexOf()!=-1仅在传递的字符串不为空时才有效。 所以

 'Milan'.indexOf('M') // = 0 'Milan'.indexOf('Q') // = -1 'Milan'.indexOf('') // = 0 !! 

因此,如果您的搜索字符串为空,则doSearch()实际上会将包含任何城市的所有记录添加到搜索结果中,如果它还有任何国家/地区,则添加相同的记录

最后一位导致具有相同id的多个项目的搜索结果。 并且反应不喜欢那样。

另外:如果你有一个城市=“巴黎”的记录,而国家是“法国”,那么你搜索“r”的查询将导致同样的错误。 字母“r”在城市 – >记录被添加。 字母“r”也在国家 – > 将再次添加相同的记录

完整的解决方案还需要确保每个记录只添加一次:

 if ( queryText == '' // if no search, then show all || s.support_title.toLowerCase().indexOf(queryText)!=-1 || (s.city && s.city.toLowerCase().indexOf(queryText)!=-1) || (s.country && s.country.toLowerCase().indexOf(queryText)!=-1) ){ queryResult.push(s); } 

这可确保每条记录仅添加一次。

旁注:您填写卡片的方式可以简化,并且有一些不必要的代码。 你也可以这样做:

 cards = this.props.data.map(function(s) {