【问题标题】:Fetching from REST API and storing json response for further filtering of data从 REST API 获取并存储 json 响应以进一步过滤数据
【发布时间】:2018-04-21 21:56:19
【问题描述】:

我一直在尝试使用 React 和 REST API 进行应用开发。我有一个 wordpress 网站,并且正在使用 WP Rest API。我已成功从我想要的类别中获取所有帖子。我希望能够根据该数据显示结果的不同视图/过滤器,但我不想为每个过滤器重做提取,因为所有数据都是从第一个 GET 请求中检索的。

我的问题是如何将 json 响应存储为对象或其他东西,以便当用户单击过滤器(例如,仅显示 2017 年的帖子)时,程序将遍历它已经获取的对象一次,只提取 2017 年的那些。

目前我有我想要的功能,但我在 fetch 的成功回调中对所有可能的列表视图进行了“硬编码”。所以我创建了所有可能的列表,然后我的按钮在每个列表之间来回切换。这对我来说似乎并不“正确”,我想不是在一个地方进行所有迭代而是在用户选择过滤器时更快。您可以在下面看到处理请求和列表显示的模块的代码。这是在 React 中制作的。

欢迎任何有关如何处理这种情况的建议,即使最终我这样做的方式是最好的方法!谢谢

import React from 'react';
import Ebook from './Ebook';


class EbookList extends React.Component {

constructor(props){
    super(props);
    this.state = {
        allPosts : [],
        revista : [],
        boletin: [],
        filterBy : 'revista'
    }

    this.fetchPosts = this.fetchPosts.bind(this);
    this.filterList = this.filterList.bind(this);
    this.handleClick = this.handleClick.bind(this);
    //this.renderSomething = this.renderSomething.bind(this);
}
fetchPosts(){

    const url = 'https://cipm.org.mx/wp-json/wp/v2/posts?categories=15&per_page=50';

    fetch(url).then(response => {
      if(response.ok){
        return response.json();

      }
      throw new Error('Fetch failed');

    },networkError=>console.log(networkError.message)).then(
    responseJson=>{

      console.log(responseJson.length);

      let postList = responseJson.map(post => {
        // console.log(post.date);
       return <Ebook ebookData={post} key={post.id} />
      });

      let boletinList = responseJson.map(post => {
        //tag 17 is revista
        //tag 16 is boletin
        if(post.tags.includes(16)){
            return <Ebook ebookData={post} key={post.id} />
        } return null;
      });

      let revistaList = responseJson.map(post => {
        //tag 17 is revista
        //tag 16 is boletin
        if(post.tags.includes(17)){
            return <Ebook ebookData={post} key={post.id} />
        }return null;
      });
      let yearList = responseJson.map(post=>{
        if(post.date===2018){
            return <Ebook ebookData={post} key={post.id} />
        }return null;
      })
       this.setState({
        allPosts:postList,
        boletin:boletinList,
        revista:revistaList,
        year: yearList
       });
       // console.log("the state object: " + this.state.jsonObject[0]);
       console.log(responseJson);
       console.log(postList);



    });
}

filterList(){
    if(this.state.filterBy === 'boletin'){
        return this.state.boletin;

    } else if (this.state.filterBy === 'revista'){
        return this.state.revista;
    } else if (this.state.filterBy === 'viewAll'){
        return this.state.allPosts;
    }
}

handleClick(event){

    this.setState({filterBy:event.target.value});
}
componentDidMount(){
    this.fetchPosts();
 }


render(){
    // {this.props.dataObject.map(ebook =>{
        //  return <Ebook ebookData={ebook} />
        //  })}
    return (
        <div className="ebookList-container">
            <div className="ebookList-controls">
                <button onClick={this.handleClick} value='viewAll' >Todos</button>
                <button onClick={this.handleClick} value='boletin'>Boletin</button>
                <button onClick={this.handleClick} value='revista'>Revista</button>
            </div>
            <div className="ebookList-container">
                {this.filterList()}
            </div>
        </div>  
    );
}
}

export default EbookList;

【问题讨论】:

    标签: javascript reactjs rest api fetch


    【解决方案1】:

    我猜你可以在 fetch 方法中存储 allPosts 并在 filterList 方法中实现过滤算法

    类似的东西应该可以工作

    filterList = () => {
        if(this.state.filterBy === 'boletin'){
            return getBoletin(this.state.allPosts);
        } else if (this.state.filterBy === 'revista'){
            return getRevista(this.state.allPosts);
        } else if (this.state.filterBy === 'viewAll'){
            return this.state.allPosts;
        }
    }
    
    getBoletin = (posts) => {
        return posts.map(post => {
        //tag 17 is revista
        //tag 16 is boletin
        if(post.tags.includes(16)){
            return <Ebook ebookData={post} key={post.id} />
        } return null;
      });
    }
    
    getRevista = (posts) => {
        return posts.map(post => {
        //tag 17 is revista
        //tag 16 is boletin
        if(post.tags.includes(17)){
            return <Ebook ebookData={post} key={post.id} />
        }return null;
      });
    }
    
    ....
    

    【讨论】:

    • 是的,我明白了这背后的想法,这就是我想要实现的目标,但是我不确定在 state{allPosts} 中存储什么,因为该状态正在存储带有组件和属性的 JSX,它是不将整个响应存储为对象或任何东西。我已经尝试将整个响应存储在状态中,但是当我控制台记录它时,它只是说 [object] 并且我看不到任何实际值。因此,一旦我能够将整个 json 响应存储到状态而不是迭代数组中,您建议的这种方法就会起作用。不确定如何将整个响应存储为对象
    • 其实我已经尝试了一些东西,我认为你是完全正确的,让我试试这个,稍后我会回复你
    • 要将数组更改为对象,您可以使用 reduce() 方法 - link
    • 非常感谢!这对我帮助很大。由于这一点,我能够进一步降低复杂性
    • 不用担心。您也可以使用以下内容摆脱 map 操作中的 if 语句。 post.filter(post => post.tags.includes(16)).map(post => )。你会避免使用 null 元素,让一些东西更容易阅读。
    猜你喜欢
    • 2019-12-22
    • 1970-01-01
    • 2018-01-17
    • 2023-03-04
    • 2017-01-21
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多