如何使用通过道具传递的字符串过滤组件的内容?
How to filter through content of component with a string passed through the props?
在 parent 组件中有一个文本字段,我想过滤多个 child 组件,其中字符串通过 props 传递。 child 组件已通过映射函数输出,该函数也将数据从 API 导入道具。在作为道具传递给 child (searchTerm) 后,我有用户输入控制台日志记录。我的问题是我无法根据用户的输入隐藏单个组件的显示。我遇到的麻烦是,当一个人决定隐藏自己时——他们都会这样做。我试过 indexOf 并发现 include() 更有用。我很担心我解决这个问题的方法,并希望从经验丰富的 React 开发人员那里得到一些智慧。
//parent分量
render() {
return (
<React.Fragment>
<input type="text" className = {styles.searchField} id="searchField" placeholder = "Search..." onChange = {this.getUserInput}/>
<div className={styles.container}>
{this.state.importedBooks.map((element, index) => (
<Tile key ={index} searchTerm ={this.state.searchTerm} buy ={element.amazon_product_url}
img ={element.book_image} summary ={element.description} url={element.book_image}
book_author ={element.author} book_title ={element.title} />
))}
</div>
</React.Fragment>);
}
}
//child分量
class 瓷砖延伸 React.Component {
public state:{display:boolean} = {display:true};
public getContainerContent = () => {
const containers: NodeListOf<Element> | null = document.querySelectorAll("#container");
containers.forEach(element => {
if (element.innerHTML.toLocaleLowerCase().includes(this.props.searchTerm) !== false) {
this.setState({display:true});
}
else if (this.props.searchTerm == "") {
this.setState({display:true});
}
else {
this.setState({ display: false });
}
})
};
public componentWillReceiveProps = () => {
this.getContainerContent();
}
render() {
const renderContainer = this.state.display ? styles.container : styles.hideDisplay;
return (
<div className={styles.container} id="container">
<h1>{this.props.book_title}</h1>
<h2>{this.props.book_author}</h2>
<a href={this.props.buy} target="_blank"><img src = {this.props.img} alt="book cover"/></a>
<p>{this.props.summary}</p>
<a href={this.props.buy} target="_blank">Purchase</a>
</div> );
}
}
我认为问题出在您的子组件中的 getContainerContent
方法。
为什么单个子组件会关心属于其他子组件的数据?
解决此问题的一种方法是首先在父组件中声明 在显示子组件时,您要将哪些道具与过滤器匹配。
然后,您可以遍历这些声明的道具并决定组件是否应该 显示子组件或不 .
// parent comp
private shouldDisplayElement (element, searchTerm: string): boolean {
const propsToMatchFiltersAgainst = ['book_title', 'book_author', 'buy', /* etc... */];
let shouldDisplay = false;
for (const p of propsToMatchFiltersAgainst) {
if (`${element[p]}`.toLowerCase().includes(searchTerm.trim())) {
shouldDisplay = true;
}
}
return shouldDisplay;
}
// parent's render fn
<div className={styles.container}>
{this.state.importedBooks.map((element, index) => (
this.shouldDisplayElement(element, this.state.searchTerm)
? <Tile
key={index}
buy={element.amazon_product_url}
img={element.book_image}
summary={element.description}
url={element.book_image}
book_author={element.author} book_title={element.title}
/>
: null
))}
</div>
这样,鉴于目前的情况,您不需要再在子组件中使用 getContainerContent
方法。
在 parent 组件中有一个文本字段,我想过滤多个 child 组件,其中字符串通过 props 传递。 child 组件已通过映射函数输出,该函数也将数据从 API 导入道具。在作为道具传递给 child (searchTerm) 后,我有用户输入控制台日志记录。我的问题是我无法根据用户的输入隐藏单个组件的显示。我遇到的麻烦是,当一个人决定隐藏自己时——他们都会这样做。我试过 indexOf 并发现 include() 更有用。我很担心我解决这个问题的方法,并希望从经验丰富的 React 开发人员那里得到一些智慧。
//parent分量
render() {
return (
<React.Fragment>
<input type="text" className = {styles.searchField} id="searchField" placeholder = "Search..." onChange = {this.getUserInput}/>
<div className={styles.container}>
{this.state.importedBooks.map((element, index) => (
<Tile key ={index} searchTerm ={this.state.searchTerm} buy ={element.amazon_product_url}
img ={element.book_image} summary ={element.description} url={element.book_image}
book_author ={element.author} book_title ={element.title} />
))}
</div>
</React.Fragment>);
}
}
//child分量
class 瓷砖延伸 React.Component {
public state:{display:boolean} = {display:true};
public getContainerContent = () => {
const containers: NodeListOf<Element> | null = document.querySelectorAll("#container");
containers.forEach(element => {
if (element.innerHTML.toLocaleLowerCase().includes(this.props.searchTerm) !== false) {
this.setState({display:true});
}
else if (this.props.searchTerm == "") {
this.setState({display:true});
}
else {
this.setState({ display: false });
}
})
};
public componentWillReceiveProps = () => {
this.getContainerContent();
}
render() {
const renderContainer = this.state.display ? styles.container : styles.hideDisplay;
return (
<div className={styles.container} id="container">
<h1>{this.props.book_title}</h1>
<h2>{this.props.book_author}</h2>
<a href={this.props.buy} target="_blank"><img src = {this.props.img} alt="book cover"/></a>
<p>{this.props.summary}</p>
<a href={this.props.buy} target="_blank">Purchase</a>
</div> );
}
}
我认为问题出在您的子组件中的 getContainerContent
方法。
为什么单个子组件会关心属于其他子组件的数据?
解决此问题的一种方法是首先在父组件中声明 在显示子组件时,您要将哪些道具与过滤器匹配。
然后,您可以遍历这些声明的道具并决定组件是否应该 显示子组件或不 .
// parent comp
private shouldDisplayElement (element, searchTerm: string): boolean {
const propsToMatchFiltersAgainst = ['book_title', 'book_author', 'buy', /* etc... */];
let shouldDisplay = false;
for (const p of propsToMatchFiltersAgainst) {
if (`${element[p]}`.toLowerCase().includes(searchTerm.trim())) {
shouldDisplay = true;
}
}
return shouldDisplay;
}
// parent's render fn
<div className={styles.container}>
{this.state.importedBooks.map((element, index) => (
this.shouldDisplayElement(element, this.state.searchTerm)
? <Tile
key={index}
buy={element.amazon_product_url}
img={element.book_image}
summary={element.description}
url={element.book_image}
book_author={element.author} book_title={element.title}
/>
: null
))}
</div>
这样,鉴于目前的情况,您不需要再在子组件中使用 getContainerContent
方法。