【问题标题】:filtering through an array of JSON objects by UI通过 UI 过滤 JSON 对象数组
【发布时间】:2019-12-02 05:29:33
【问题描述】:

我想显示一个带有搜索栏的狗列表,在该搜索栏上方输入时只会显示符合条件的狗。

我之前将数组存储在 state 中,一切正常。然而现在,期待一旦启动并运行,我将在数组中有数千个条目,它会变得太乱。所以我决定我希望以 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;

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

【问题讨论】:

  • 您好,当您在 DogList 函数中映射 json 数据时,postDetail 的值是多少,您可以控制台记录该值吗?另外,当您要搜索时收到的错误消息是什么?
  • "当我在搜索栏中输入时,我收到一条错误消息。"
  • TypeError:无法读取 null 的属性“toString”(匿名函数)C:/Users/corey/Desktop/said1/src/components/dogslist.js:34 31 | 32 |渲染() { 33 | > 34 |让filteredDogs = this.state.dogs.filter(dog => Object.values(dog).some( | ^ 35 | val => val.toString().toLowerCase().includes(this.state.searchDog.toLowerCase( )))) 36 | 37 |返回(
  • 您传递的道具与您尝试使用的道具不同。 &lt;Dog Name={postDetail.title} 但在 Dog 中,您尝试使用密钥 title 而不是 Name。也许你想做的是&lt;Dog postDetail={postDetail}
  • 为什么你所在的州有 jsx?在 DogsList 中,您正在使用 jsx 定义状态。

标签: javascript json reactjs


【解决方案1】:

在您的列表组件中,您将不正确的道具传递给 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;

【讨论】:

  • 感谢清晰,我现在收到此错误。 filtersDogs.map 不是函数 6 |函数 DogList(filteredDogs){ > 7 |让狗=filteredDogs.map((dog) => { 8 | return 9 | }) 10 |返回(
  • 你能在 let dogs = filteredDogs.map((dog) => { 之前 console.log(filteredDogs) 看看它显示了什么吗?
【解决方案2】:

你的问题是你在你的状态中定义 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>
  )
};

【讨论】:

  • 感谢 John,但我之前确实将数据存储在 state 中,但是因为我最终想要拥有数千个对象,所以我认为数组会变得太长和混乱。 (每个对象会有更多的道具和图像)。所以我想将数据存储为 JSON,因为我认为它会使我的代码更整洁。
  • 然后实现分页,或者无限加载。可能还有像 redux 这样的状态管理系统
  • 这不会解决问题,因为子组件中传递了不正确的道具。
  • 嗯,好的,明白了:)
  • 你应该有条件地渲染它。 {hasFacebookUrl ? &lt;Fbook /&gt; : null }
猜你喜欢
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多