Maximum update depth exceeded - React

问题: I am building a react application in which user enters a search word and backend gives array of json. On the result page I am trying to implement faceted search, so I have...

问题:

I am building a react application in which user enters a search word and backend gives array of json. On the result page I am trying to implement faceted search, so I have few filters. I am filtering the fetched result based on the user chosen checkboxes. Here is the UI. enter image description here

This is my js file for the search results page.

import React from 'react';
import NavigationBar from './NavigationBar';
import SearchPageResultsStyle from "../assets/css/SearchResultsPage.css"
import Pagination from './Pagination';

class SearchResultsPage  extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            results: this.props.location.state.data.results,
            keyword: this.props.location.state.data.keyword,
            pageOfItems: [],
            cities: {
                'New York City (NYC)': false,
                'Delhi': false,
                'Bangkok': false,
                'Paris': false,
                'Mexico City': false
            },
            topics: {
                'Environment': false,
                'Crime': false,
                'Politics': false,
                'Social Unrest': false,
                'Infrastructure': false
            },
            languages: {
                'Hindi': false,
                'English': false,
                'Thai': false,
                'French': false,
                'Spanish': false
            }
        };
        this.onChangePage = this.onChangePage.bind(this);
        this.onCityChange = this.onCityChange.bind(this);
    }

    componentDidUpdate(prevProps, prevState) {
        if (prevState !== this.state) {
            console.log(this.state.cities);
            const filteredCities = [];
            for (let key in this.state.cities) {
                if (this.state.cities[key] === true) {
                    filteredCities.push(key)
                }
            }
            console.log(filteredCities);
            const filteredResults = [];
            this.state.results.forEach((result) => {
                for (let i = 0; i < filteredCities.length; i++) {
                    if (result.city === filteredCities[i]) {
                        filteredResults.push(result)
                    }
                }
            })
            console.log("fileterdPageOfItems", filteredResults)
            this.updatePageOfItems(filteredResults)

        }
    }

    // Function to filter the search results based on user chosen filters
    updatePageOfItems(filteredResults) {
        this.setState({
            results: filteredResults
        })
    }

    onChangePage(pageOfItems) {
        // update local state with new page of items
        this.setState({pageOfItems});
    }

    // setting each city in cities object (city chechboxes which are clicked on UI) to true
    onCityChange(e) {
        const val = e.target.checked;
        const name = e.target.name;
        let updatedCities = Object.assign({},this.state.cities,{[name]: val});
        this.setState({
            cities: updatedCities,
        })
    }

    // rendering checkboxes for cities
    renderCity() {
        const cities = ['New York City (NYC)','Delhi','Bangkok','Paris','Mexico City']
        return cities.map((city,i) => {
            return (
                <div>
                    <label key={i}>
                        {city}
                        <input
                            type="checkbox"
                            name={city}
                            onChange={this.onCityChange}
                            value={this.state.cities[city]}/>
                    </label>
                </div>

            )
        })
    }

    render() {

        const renderItems = this.state.pageOfItems.map((item, index) => {
            return (
                <div>
                    <h3 style={{color: '#1a0dab'}} key={index}>{item.text}</h3>
                    <a href={'https://google.com'} key={index}>{item.tweetUrl}</a>
                    <br/>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>topic: </span>{item.topic}</p>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>city: </span>{item.city}</p>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>lang: </span>{item.lang}</p>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>Hashtags: </span></p>
                    <hr/>
                </div>
            )
        });

        return (
            <div>
                <NavigationBar/>
                <h4 style={{textAlign:'center', color:'#1a0dab'}}>Showing search results for <span style={{fontWeight:'bold', fontStyle:'Italic'}}>'{this.state.keyword}'</span></h4>
                <hr/>
                <div className={'wrap'} style={SearchPageResultsStyle}>
                    <div className={'fleft'}>
                        <h4>City</h4>
                        {this.renderCity()}
                        <hr/>
                        <h4>Topics</h4>
                        <hr/>
                        <h4>Language</h4>
                        <hr/>
                    </div>
                    <div className={'fcenter'}>
                        {renderItems}
                        <Pagination items={this.state.results} onChangePage={this.onChangePage}/>
                    </div>
                    <div className={'fright'}></div>
                </div>
            </div>
        )
    }

}

export default SearchResultsPage;

I am updating the cities in my state to true whenever a user clicks on a particular checkbox, and then I am filtering the fetched result (from backend) based on the cities in my array filteredCities and I am collecting the filtered results in an array filteredResults, and then I am passing this array to a function updatePageOfItems to change the state so that my filtered result could get re-rendered. But When I am calling the function updatePageOfItems, the application is getting into infinite loop. What is the work around for this problem. I am new to react and facing this issue for the first time.

Here is the stack trace enter image description here


回答1:

I was able to solve the issue, instead of filtering the results in the function componentDidUpdate I did the operation in the callback function of setState inside onCityChange function.

onCityChange(e) {
        const val = e.target.checked;
        const name = e.target.name;
        let updatedCities = Object.assign({},this.state.cities,{[name]: val});
        this.setState({
            cities: updatedCities,
        },function () {
            const filteredCities = [];
            for (let key in this.state.cities) {
                if (this.state.cities[key] === true) {
                    filteredCities.push(key)
                }
            }
            console.log("filteredCities", filteredCities);
            const filteredResults = [];
            this.state.results.forEach((result) => {
                for (let i = 0; i < filteredCities.length; i++) {
                    if (result.city === filteredCities[i]) {
                        filteredResults.push(result)
                    }
                }
            })
            this.setState({
                results: filteredResults
            },function () {
                console.log(this.state.results)
            })
        })
    }

  • 发表于 2019-01-15 05:00
  • 阅读 ( 368 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除