使用 reactjs 和 axios 防止 json 数组重复

Posted

技术标签:

【中文标题】使用 reactjs 和 axios 防止 json 数组重复【英文标题】:Prevent duplicates from json array with reactjs and axios 【发布时间】:2019-05-06 09:01:38 【问题描述】:

看看我与 @Akrion 的对话下方的我的 cmets,他帮助我解决了这个问题!!!!

我对 reactJS 和 axios 都很陌生,但之前和同学一起尝试过,现在我被卡住了。我想从 json 文件中渲染“运动”类别,但相同的类别会出现多次。什么是对重复项进行分类的好习惯,以便仅例如“足球”出现一次?

再次抱歉,这是新手。我一直在尝试一些诸如 javascript 函数之类的东西来对其进行排序......但我只是不确定将代码放在哪里,我一直在转圈。如果我说的任何内容令人困惑,请告诉我(英语不是我的第一语言)。这是我的代码:

import React,  Component  from "react";
import axios from 'axios';

class SportsList extends Component 
  state = 
    posts: []
  
  componentDidMount()
    axios.get('https://json-file.json')
    .then(res => 
      this.setState(
        posts: res.data
      )
    )  
  

  render() 
    console.log(this.props)
    const  posts  = this.state;
    const postList = posts.length ? (
        posts.map(post => 
          return (
            <div key=post.id>
              <div>
                post.sport
              </div>
            </div>
          )
        )
      ) : (
        <div>No Sports Available</div>
      )
    return (
      <div> 
      postList
    </div>
    );
  


export default SportsList;

【问题讨论】:

使用Set 而不是基本数组。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 【参考方案1】:

理想情况下,您应该在服务器端修复数据,但您也可以在前端删除重复数据:

res.data.reduce((acc, post) => 
  const post1 = acc.find(x => x.sport === post.sport);
  if (!post1) 
    acc.push(post1);
  
  return acc;
, []);

不是最有效的方法,但很简单

【讨论】:

@Joel8bitar 在您的 setState 中使用:this.setState( posts ),其中posts 是上述函数调用的返回值 所以只用“posts:”之后的“res.data”行替换它?【参考方案2】:

您也可以通过Array.reduce 简单地按您的帖子ID 分组,然后获取值。将您的 render 更改为:

render() 
    const  posts  = this.state;
    const uniquePosts = Object.values(posts.reduce((r,c) =>  
      r[c.id] = c 
      return r
    , ))
    const postList = uniquePosts.length ? (
        uniquePosts.map(post => 
          return (
            <div key=post.id>
              <div>
                post.sport
              </div>
            </div>
          )
        )
      ) : (<div>No Sports Available</div>)
    return (<div>postList</div>);
  

【讨论】:

我还没有很好地理解错误,但我得到了:./src/components/SportsList.js 第 19 行:解析错误:意外的令牌,预期的“,” 17 |渲染() 18 |常量 帖子 = this.state; > 19 | const uniquePosts = Object.values(posts.reduce(r,c) => (r[c.id] = c,r), ) | ^ 20 |常量 postList = uniquePosts.length ? ( 21 | uniquePosts.map(post => 22 | 返回 ( 我认为它缺少 "Object.values(" 的右括号,我猜它是在行尾?但如果我把它放在那里,我仍然会得到所有重复项。 抱歉:配音? uniquePosts 正在获取它看起来的所有现有匹配项。然后我得到:“第 18 行:意外使用逗号运算符无序列:”'c,r), ))' 啊,当然对不起。这里有点晚了......我试过了。仍然得到所有重复项。 今天又看了一遍你的小提琴。在我的编辑器中编写并稍微更改了数据,然后我意识到在查看“r[c.id] = c”时,我只需将“id”更改为“sport”。现在工作。谢谢大家的帮助!【参考方案3】:

您可以在渲染之前使用 reduce 过滤运动,例如在 setState 之前

const sportsFiltered = sports.reduce((accum, sport) => 
    const accumulator = [...accum];
    if(!accumulator.some(item => item.id === sport.id)) 
        accumulator.push(sport);
    
    return accumulator;
,[]);

class SportsList extends Component 
  state = 
    posts: []
  
  componentDidMount()
    axios.get('https://json-file.json')
    .then(res => 
      this.setState(
        posts: sportsFiltered(res.data)
      )
    )  
  

  render() 
    console.log(this.props)
    const  posts  = this.state;
    const postList = posts.length ? (
        posts.map(post => 
          return (
            <div key=post.id>
              <div>
                post.sport
              </div>
            </div>
          )
        )
      ) : (
        <div>No Sports Available</div>
      )
    return (
      <div> 
      postList
    </div>
    );
  

【讨论】:

紧跟在render() 之后?我只得到“未定义运动”。【参考方案4】:
const newPosts = [...new Set(posts)]

【讨论】:

以上是关于使用 reactjs 和 axios 防止 json 数组重复的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 axios 和 ReactJS 执行获取请求

使用 axios 和 ReactJS 进行反应选择后如何获取数据?

ReactJS 和 Django:如何以正确的方式使用 axios 发送 csrf 令牌?

ReactJS 和 Express 与 Axios 返回 404

axios 和 reactjs:预检响应具有无效的 HTTP 状态代码 400

reactjs-Axios 帖子返回空对象