我想显示带有搜索栏的狗的列表,在上面键入时将仅显示符合条件的狗。
我以前将数组存储在状态中,并且一切正常。但是,现在,一旦启动并运行,我将在数组中包含成千上万个条目,并且它会变得太乱了。因此,我决定希望以JSON格式存储我的所有对象,因为我相信它将更容易管理。
我被困住了,我试图将.json文件集成到旧格式中,但是我没有收到任何数据,当我在搜索栏中键入内容时,会收到错误消息。
这是我的json:
[
{
"id": 3,
"title": "Sir",
"content":"My name is Sir Jeffrey"
},
{
"id": 4,
"title": "Prince",
"content": "My name is Prince Gareth"
},
{
"id": 5,
"title": "Princess",
"content": "My name is Princess Roy Roy"
},
{
"id": 6,
"title": "King",
"content": "My name is King George"
}
]
我的App.js:
import React from 'react';
import './App.css';
import DogsList from './components/dogslist.js';
function App() {
return (
<div className="App">
<DogsList/>
</div>
);
}
export default App;
我的列表功能:
import React, {Component} from 'react';
import Dog from './listlayouts.js';
function DogList(postDetail){
let dogs = postDetail.filteredDogs.map((dog, i) => {
return <Dog key={postDetail.id} Name={postDetail.title} Content=
{postDetail.content}/>
})
return(
<div>
{dogs}
</div>
)
};
export default DogList;
列表布局:
import React, {Component} from 'react';
function Dog(postDetail){
return(
<div>
<p>Name: {postDetail.title}</p>
<p>Content: {postDetail.content}</p>
</div>
)
}
export default Dog;
搜索框功能:
import React, {Component} from 'react';
function DogSearchBox(postDetail){
return (
<div>
<input onChange={postDetail.handleInput} type ='text'/>
</div>
)
}
export default DogSearchBox;
以及Doglist组件,该组件应在所有狗列表上方显示一个空的搜索栏,然后,一旦用户在搜索栏中键入内容,该列表便应更改。
import React, {Component} from 'react';
import DogList from './listfunctions.js';
import DogSearchBox from './searchboxfunctions.js';
import postData from './dogs.json';
class DogsList extends Component {
constructor(props){
super(props);
this.state = {
dogs: [
<div>
{postData.map((postDetail, index) => {
return(
<div>
<h2>{postDetail.title}</h2>
<p>{postDetail.content}</p>
</div>
)
})}
</div>
],
searchDog:''
}
}
handleInput = (e) => {
this.setState({searchDog: e.target.value})
}
render() {
let filteredDogs = this.state.dogs.filter(dog =>
Object.values(dog).some(val =>
val.toString().toLowerCase().includes
(this.state.searchDog.toLowerCase())))
return (
<div>
<header>
<h1>Dogs</h1>
</header>
<div>
<DogSearchBox handleInput = {this.handleInput}/>
<DogList filteredDogs = {filteredDogs}/>
</div>
</div>
);
}
}
export default DogsList;
我对这一切仍然陌生,但是我有一种感觉,我将不再需要所有这些组件。然后,我更乐意尽可能简化它。只要它能按预期工作。
答案 0 :(得分:3)
问题在于,您正在状态中定义JSX元素。然后,您尝试将其转换为字符串。
class DogsList extends Component {
constructor(props){
super(props);
this.state = {
dogs: [
<div>
// -----^--------------
{postData.map((postDetail, index) => {
return(
<div>
<h2>{postDetail.title}</h2>
<p>{postDetail.content}</p>
</div>
)
})}
</div>
// -------^--------------
],
searchDog:''
}
}
相反,您应该只将数据存储为状态,在渲染期间创建元素
class DogsList extends Component {
constructor(props){
super(props);
this.state = {
dogs: [...postData],
searchDog:''
}
}
render() {
const filteredDogs = ...
return <div>
<DogList dogs={filteredDogs} />
</div>
}
}
然后解决将错误的道具传递给狗组件的问题
function DogList({dogs){
let elems = dogs.map((dog, i) => {
return <Dog key={dog.id} {...dog} />
})
return(
<div>
{elems}
</div>
)
};
答案 1 :(得分:2)
在列表组件中,您正在将错误的道具传递给Dog
组件,请尝试将其更改为:
function DogList(filteredDogs){
let dogs = filteredDogs.map((dog) => {
return <Dog key={dog.id} dog={dog} />
})
return(
<div>
{dogs}
</div>
)
};
,然后在布局组件中,您可以通过以下方式访问道具:
function Dog(dog){
return(
<div>
<p>Name: {dog.title}</p>
<p>Content: {dog.content}</p>
</div>
)
}
编辑:而且看来您没有在主组件中传递正确的数据。通过删除不必要的dogs
状态并将帖子数据直接传递到过滤器,将其更改为此:
class DogsList extends Component {
constructor(props){
super(props);
this.state = {
searchDog:''
}
}
handleInput = (e) => {
this.setState({searchDog: e.target.value})
}
render() {
let filteredDogs = postData.filter(dog =>
Object.values(dog).some(val =>
val.toString().toLowerCase().includes
(this.state.searchDog.toLowerCase())))
return (
<div>
<header>
<h1>Dogs</h1>
</header>
<div>
<DogSearchBox handleInput = {this.handleInput}/>
<DogList filteredDogs = {filteredDogs}/>
</div>
</div>
);
}
}
export default DogsList;