通过UI过滤JSON对象数组

时间:2019-07-24 06:24:52

标签: javascript json reactjs

我想显示带有搜索栏的狗的列表,在上面键入时将仅显示符合条件的狗。

我以前将数组存储在状态中,并且一切正常。但是,现在,一旦启动并运行,我将在数组中包含成千上万个条目,并且它会变得太乱了。因此,我决定希望以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;

我对这一切仍然陌生,但是我有一种感觉,我将不再需要所有这些组件。然后,我更乐意尽可能简化它。只要它能按预期工作。

2 个答案:

答案 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;