【问题标题】:Maximum update depth exceeded - React超过最大更新深度 - 反应
【发布时间】:2019-01-13 20:45:25
【问题描述】:

我正在构建一个反应应用程序,用户在其中输入搜索词,后端提供 json 数组。在结果页面上,我正在尝试实现分面搜索,所以我的过滤器很少。我正在根据用户选择的复选框过滤获取的结果。这是用户界面。

这是我的搜索结果页面的 js 文件。

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;

每当用户单击特定复选框时,我都会将我所在州的城市更新为 true,然后根据数组 filteredCities 中的城市过滤获取的结果(从后端),并收集过滤后的结果生成数组filteredResults,然后我将此数组传递给函数updatePageOfItems 以更改状态,以便我的过滤结果可以重新呈现。但是当我调用函数updatePageOfItems 时,应用程序进入了无限循环。 这个问题的解决方法是什么。我是新手,第一次面对这个问题。

这是堆栈跟踪

【问题讨论】:

  • 错误已经说明了一切。在您的componendDidUpdate 中,您总是在更改状态。 if (prevState !== this.state) 总是正确的。这个状态改变触发componentDidUpdate,它触发状态改变,触发componentDidUpdate,以此类推……
  • @quirimmo 那么我应该应用什么检查,以避免这种情况......
  • 我不知道这里发生了什么。是的,我知道您正在搜索和过滤结果,但这对于简单的搜索来说确实是一团糟而且过于复杂。在我个人看来,从零开始重新设计你的组件逻辑,让事情尽可能简单。
  • 恕我直言,修复您提到的错误,然后将此代码放在代码审查中可以帮助您很多
  • @Treycos 我在哪里放置我的代码以进行代码审查,是否有单独的门户或这里本身???

标签: javascript reactjs


【解决方案1】:

我能够解决问题,而不是在函数componentDidUpdate 中过滤结果,而是在onCityChange 函数内的setState 的回调函数中进行了操作。

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)
            })
        })
    }

【讨论】:

    猜你喜欢
    • 2021-07-12
    • 2019-02-14
    • 2019-07-17
    • 2021-05-15
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 2021-06-20
    相关资源
    最近更新 更多