嗨,我可以访问联系人姓名Ron并在其中使用过滤器。但是,我无法访问孩子联系Alex并在过滤器中使用它。我附上了输出截图。我需要在其中打印儿童Alex并使用过滤器。提前谢谢
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
let arr = [{"id":1,
"number":true,
"location":"2",
"time":11,
"code":1001,
"name":"Ron",
"children":[{
"id":141,
"number":true,
"location":1,
"time":1504969439000,
"code":null,
"name":"Alex"}]}]
const Tab = ({ value }) => <div> {value} </div>;
class App extends React.Component {
constructor() {
super();
this.state ={
search: ''
};
}
updateSearch(event){
this.setState({search: event.target.value.substr(0,20)})
}
render() {
let filteredContacts = arr.filter((item)=>{
return item.name.toLowerCase().indexOf(this.state.search)!==-1;
});
return(<div>
<h1> Contact List </h1>
<input type="text"
value={this.state.search}
placeholder="Search Here"
onChange={this.updateSearch.bind(this)} />
<ul>
{
filteredContacts.map((obj, i) =>
<Tab value={obj.name} key={i} />)
}
</ul>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('container'));
答案 0 :(得分:1)
您的过滤只会遍历数组中的第一级联系人,因此.children
中的所有联系人都不会被显示或过滤掉。
你想要做的是创建一个包含所有联系人的数组,但是将它们放在同一个“底部”级别([{name: 'Ron'}, {name: 'Alex'}]
),以便我们可以过滤 而不是数组。
这样做的一种方法是首先.map
超过原始数组,并确保我们同时获得“底部”(父)联系人和一个数组中的子项:(如果...
语法对你而言是新的,scroll to 'Spread in array literals' here)
const allContacts = originalContacts.map(parentContact => [parentContact, ...parentContact.children])
但是这会让我们得到一个数组:[[{name: 'Ron'}, {name: 'Alex'}]]
,这很难处理。所以我们想要创建一个新数组,我们将allContacts
数组中的所有数组连接成一个数组。幸运的是,有一种方法可以调用在数组中接受参数的.concat
方法。它看起来有点奇怪,但我们可以这样做:(更多关于.apply
)
const allContactsFlattened =
Array.prototype.concat.apply([], allContacts);
所以现在我们拥有了我们想要的东西:所有联系人的“平面”(一级)数组。您的过滤方法已经知道如何处理,因此不必进行进一步的更改。
要查看它的实际效果,我将您的代码包含在应用的更改中(以稍微不同的方式)+一些注释:
let originalContacts = [
{"name":"Ron (parent)", "children":[{"name":"Alex (child)"}, {"name":"Emma (child)"}]},
{"name":"Isa (parent)", "children":[{"name":"Sarah (child)"}, {"name":"Ahmad (child)"}]}
];
const Tab = ({ value }) => <div> {value} </div>;
class App extends React.Component {
constructor() {
super();
this.state ={
search: ''
};
}
updateSearch(event){
this.setState({search: event.target.value.substr(0,20)})
}
render() {
let contactsAndSubContacts =
// flatten the result
Array.prototype.concat.apply(
// transform from parent => [parent, child1, child2 etc..]
[], originalContacts.map(contact => [contact, ...contact.children])
);
let filteredContacts = contactsAndSubContacts.filter((item)=>{
// NOTE: you probably want to use toLowerCase()
// on this.state.search as well
return item.name.toLowerCase().indexOf(this.state.search.toLowerCase())!==-1;
});
return(<div>
<h1> Contact List </h1>
<input type="text"
value={this.state.search}
placeholder="Search Here"
onChange={this.updateSearch.bind(this)} />
<ul>
{
filteredContacts.map((obj, i) =>
<Tab value={obj.name} key={i} />)
}
</ul>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>