appbaseio / reactivesearch

Search UI components for React and Vue
https://opensource.appbase.io/reactivesearch
Apache License 2.0
4.9k stars 466 forks source link

MultiDataList causing infinite loop #271

Closed davidklebanoff closed 6 years ago

davidklebanoff commented 6 years ago

Issue Type: bug

Description:

I'm quite confused as to what may be the cause here, however it seems the MultiDataList can sometimes get stuck in an infinite loop updating its state. I was able to re-create the issue using the car example from the website. It appears to run fine when the MultiDataList is set beside another filter in the main App component. As seen in the first example below. However the 2nd, 2 file example, which places the filters into their own component causes the infinite loop.

Minimal reproduction of the problem with instructions:

The following runs fine:

App.js

import React, { Component } from 'react';
import { ReactiveBase, CategorySearch, MultiDataList, SingleRange, ResultCard } from '@appbaseio/reactivesearch';
class App extends Component {
    render() {
        return (
            <ReactiveBase
                app="car-store"
                credentials="cf7QByt5e:d2d60548-82a9-43cc-8b40-93cbbe75c34c">

                <div>
                    <MultiDataList
                        componentId="brandfilter"
                        dataField="name"
                        data={
                    [{
                        label: "bmw",
                        value: "bmw"
                    },
                    {
                        label: "audi",
                        value: "audi"
                    }]}
                        />
                    <SingleRange
                        componentId="ratingsfilter"
                        title="Filter by ratings"
                        dataField="rating"
                        data={[
                    {"start": "4", "end": "5", "label": "4 stars and up"},
                    {"start": "3", "end": "5", "label": "3 stars and up"},
                    {"start": "2", "end": "5", "label": "2 stars and up"},
                    {"start": "1", "end": "5", "label": "see all ratings"}
                    ]}
                        defaultSelected="4 stars and up"
                        />
                </div>

                <ResultCard
                    componentId="result"
                    title="Results"
                    dataField="name"
                    from={0}
                    size={5}
                    pagination={true}
                    react={{
                            and: ["brandfilter", "ratingsfilter"]
                        }}
                    onData={(res) => {
                            return {
                                image: "https://bit.do/demoimg",
                                title: res.name,
                                description: res.brand + " " + "ā˜…".repeat(res.rating)
                            }
                        }}
                    />
            </ReactiveBase>
        );
    }
}

export default App;

Where as the following creates an infinite loop (Note: 2 files):

App.js

import React, { Component } from 'react';
import { ReactiveBase, CategorySearch, MultiDataList, SingleRange, ResultCard } from '@appbaseio/reactivesearch';
import CarFilters from './filters/CarFilters';

class App extends Component {
    render() {
        return (
            <ReactiveBase
                app="car-store"
                credentials="cf7QByt5e:d2d60548-82a9-43cc-8b40-93cbbe75c34c">

                <CarFilters />

                <ResultCard
                    componentId="result"
                    title="Results"
                    dataField="name"
                    from={0}
                    size={5}
                    pagination={true}
                    react={{
                            and: ["brandfilter", "ratingsfilter"]
                        }}
                    onData={(res) => {
                            return {
                                image: "https://bit.do/demoimg",
                                title: res.name,
                                description: res.brand + " " + "ā˜…".repeat(res.rating)
                            }
                        }}
                    />
            </ReactiveBase>
        );
    }
}

export default App;

./filters/CarFilters.js


import React, { Component } from 'react';
import { MultiDataList, SingleRange } from '@appbaseio/reactivesearch';

class CarFilters extends Component {

    render() {
        return (
            <div>
                <MultiDataList
                    componentId="brandfilter"
                    dataField="name"
                    data={
                    [{
                        label: "bmw",
                        value: "bmw"
                    },
                    {
                        label: "audi",
                        value: "audi"
                    }]}
                    />
                <SingleRange
                    componentId="ratingsfilter"
                    title="Filter by ratings"
                    dataField="rating"
                    data={[
                    {"start": "4", "end": "5", "label": "4 stars and up"},
                    {"start": "3", "end": "5", "label": "3 stars and up"},
                    {"start": "2", "end": "5", "label": "2 stars and up"},
                    {"start": "1", "end": "5", "label": "see all ratings"}
                    ]}
                    defaultSelected="4 stars and up"
                    />
            </div>
        )
    }
}

export default CarFilters;

Reactivesearch version: 2.2.1

Browser: All

Anything else:


invariant.js?7313:42 Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
    at invariant (invariant.js?7313:42)
    at requestWork (react-dom.development.js?cada:10833)
    at scheduleWorkImpl (react-dom.development.js?cada:10732)
    at scheduleWork (react-dom.development.js?cada:10689)
    at Object.enqueueSetState (react-dom.development.js?cada:6212)
    at MultiDataList.Component.setState (react.development.js?99ee:237)
    at performUpdate (MultiDataList.js?9661:291)
    at executeUpdate (helper.js?d71a:1)
    at checkValueChange (helper.js?d71a:1)
    at MultiDataList.setValue (MultiDataList.js?9661:299)
    at MultiDataList.componentWillReceiveProps (MultiDataList.js?9661:98)
    at callComponentWillReceiveProps (react-dom.development.js?cada:6389)
    at updateClassInstance (react-dom.development.js?cada:6575)
    at updateClassComponent (react-dom.development.js?cada:7848)
    at beginWork (react-dom.development.js?cada:8225)
    at performUnitOfWork (react-dom.development.js?cada:10224)
    at workLoop (react-dom.development.js?cada:10288)
    at HTMLUnknownElement.callCallback (react-dom.development.js?cada:542)
    at Object.invokeGuardedCallbackDev (react-dom.development.js?cada:581)
    at invokeGuardedCallback (react-dom.development.js?cada:438)
    at renderRoot (react-dom.development.js?cada:10366)
    at performWorkOnRoot (react-dom.development.js?cada:11014)
    at performWork (react-dom.development.js?cada:10967)
    at requestWork (react-dom.development.js?cada:10878)
    at scheduleWorkImpl (react-dom.development.js?cada:10732)
    at scheduleWork (react-dom.development.js?cada:10689)
    at scheduleTopLevelUpdate (react-dom.development.js?cada:11193)
    at Object.updateContainer (react-dom.development.js?cada:11231)
    at eval (react-dom.development.js?cada:15226)
    at Object.unbatchedUpdates (react-dom.development.js?cada:11102)
    at renderSubtreeIntoContainer (react-dom.development.js?cada:15225)
    at Object.render (react-dom.development.js?cada:15290)
    at eval (index.js?99a8:6)
    at Object.<anonymous> (bundle.js:2536)
    at __webpack_require__ (bundle.js:20)
    at bundle.js:63
    at bundle.js:66
invariant @ invariant.js?7313:42
requestWork @ react-dom.development.js?cada:10833
scheduleWorkImpl @ react-dom.development.js?cada:10732
scheduleWork @ react-dom.development.js?cada:10689
enqueueSetState @ react-dom.development.js?cada:6212
Component.setState @ react.development.js?99ee:237
performUpdate @ MultiDataList.js?9661:291
executeUpdate @ helper.js?d71a:1
checkValueChange @ helper.js?d71a:1
setValue @ MultiDataList.js?9661:299
componentWillReceiveProps @ MultiDataList.js?9661:98
callComponentWillReceiveProps @ react-dom.development.js?cada:6389
updateClassInstance @ react-dom.development.js?cada:6575
updateClassComponent @ react-dom.development.js?cada:7848
beginWork @ react-dom.development.js?cada:8225
performUnitOfWork @ react-dom.development.js?cada:10224
workLoop @ react-dom.development.js?cada:10288
callCallback @ react-dom.development.js?cada:542
invokeGuardedCallbackDev @ react-dom.development.js?cada:581
invokeGuardedCallback @ react-dom.development.js?cada:438
renderRoot @ react-dom.development.js?cada:10366
performWorkOnRoot @ react-dom.development.js?cada:11014
performWork @ react-dom.development.js?cada:10967
requestWork @ react-dom.development.js?cada:10878
scheduleWorkImpl @ react-dom.development.js?cada:10732
scheduleWork @ react-dom.development.js?cada:10689
scheduleTopLevelUpdate @ react-dom.development.js?cada:11193
updateContainer @ react-dom.development.js?cada:11231
(anonymous) @ react-dom.development.js?cada:15226
unbatchedUpdates @ react-dom.development.js?cada:11102
renderSubtreeIntoContainer @ react-dom.development.js?cada:15225
render @ react-dom.development.js?cada:15290
(anonymous) @ index.js?99a8:6
(anonymous) @ bundle.js:2536
__webpack_require__ @ bundle.js:20
(anonymous) @ bundle.js:63
(anonymous) @ bundle.js:66
react-dom.development.js?cada:9747 The above error occurred in the <MultiDataList> component:
    in MultiDataList (created by Connect(MultiDataList))
    in Connect(MultiDataList) (created by CarFilters)
    in div (created by CarFilters)
    in CarFilters (created by App)
    in div (created by Styled(div))
    in Styled(div) (created by URLParamsProvider)
    in URLParamsProvider (created by Connect(URLParamsProvider))
    in Connect(URLParamsProvider) (created by ReactiveBase)
    in Provider (created by ReactiveBase)
    in ThemeProvider (created by ReactiveBase)
    in ReactiveBase (created by App)
    in App

React will try to recreate this component tree from scratch using the error boundary you provided, ReactiveBase.
logCapturedError @ react-dom.development.js?cada:9747
captureError @ react-dom.development.js?cada:10540
renderRoot @ react-dom.development.js?cada:10391
performWorkOnRoot @ react-dom.development.js?cada:11014
performWork @ react-dom.development.js?cada:10967
requestWork @ react-dom.development.js?cada:10878
scheduleWorkImpl @ react-dom.development.js?cada:10732
scheduleWork @ react-dom.development.js?cada:10689
scheduleTopLevelUpdate @ react-dom.development.js?cada:11193
updateContainer @ react-dom.development.js?cada:11231
(anonymous) @ react-dom.development.js?cada:15226
unbatchedUpdates @ react-dom.development.js?cada:11102
renderSubtreeIntoContainer @ react-dom.development.js?cada:15225
render @ react-dom.development.js?cada:15290
(anonymous) @ index.js?99a8:6
(anonymous) @ bundle.js:2536
__webpack_require__ @ bundle.js:20
(anonymous) @ bundle.js:63
(anonymous) @ bundle.js:66

invariant.js?7313:42 Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
    at invariant (invariant.js?7313:42)
    at requestWork (react-dom.development.js?cada:10833)
    at scheduleWorkImpl (react-dom.development.js?cada:10732)
    at scheduleErrorRecovery (react-dom.development.js?cada:10748)
    at captureError (react-dom.development.js?cada:10562)
    at renderRoot (react-dom.development.js?cada:10391)
    at performWorkOnRoot (react-dom.development.js?cada:11014)
    at performWork (react-dom.development.js?cada:10967)
    at requestWork (react-dom.development.js?cada:10878)
    at scheduleWorkImpl (react-dom.development.js?cada:10732)
    at scheduleWork (react-dom.development.js?cada:10689)
    at scheduleTopLevelUpdate (react-dom.development.js?cada:11193)
    at Object.updateContainer (react-dom.development.js?cada:11231)
    at eval (react-dom.development.js?cada:15226)
    at Object.unbatchedUpdates (react-dom.development.js?cada:11102)
    at renderSubtreeIntoContainer (react-dom.development.js?cada:15225)
    at Object.render (react-dom.development.js?cada:15290)
    at eval (index.js?99a8:6)
    at Object.<anonymous> (bundle.js:2536)
    at __webpack_require__ (bundle.js:20)
    at bundle.js:63
    at bundle.js:66

invariant @ invariant.js?7313:42
requestWork @ react-dom.development.js?cada:10833
scheduleWorkImpl @ react-dom.development.js?cada:10732
scheduleErrorRecovery @ react-dom.development.js?cada:10748
captureError @ react-dom.development.js?cada:10562
renderRoot @ react-dom.development.js?cada:10391
performWorkOnRoot @ react-dom.development.js?cada:11014
performWork @ react-dom.development.js?cada:10967
requestWork @ react-dom.development.js?cada:10878
scheduleWorkImpl @ react-dom.development.js?cada:10732
scheduleWork @ react-dom.development.js?cada:10689
scheduleTopLevelUpdate @ react-dom.development.js?cada:11193
updateContainer @ react-dom.development.js?cada:11231
(anonymous) @ react-dom.development.js?cada:15226
unbatchedUpdates @ react-dom.development.js?cada:11102
renderSubtreeIntoContainer @ react-dom.development.js?cada:15225
render @ react-dom.development.js?cada:15290
(anonymous) @ index.js?99a8:6
(anonymous) @ bundle.js:2536
__webpack_require__ @ bundle.js:20
(anonymous) @ bundle.js:63
(anonymous) @ bundle.js:66

invariant.js?7313:42 Uncaught (in promise) Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
    at invariant (invariant.js?7313:42)
    at requestWork (react-dom.development.js?cada:10833)
    at scheduleWorkImpl (react-dom.development.js?cada:10732)
    at scheduleWork (react-dom.development.js?cada:10689)
    at Object.enqueueSetState (react-dom.development.js?cada:6212)
    at Connect.Component.setState (react.development.js?99ee:237)
    at Connect.onStateChange (connectAdvanced.js?4805:205)
    at Object.notify (Subscription.js?3024:26)
    at Subscription.notifyNestedSubs (Subscription.js?3024:65)
    at Connect.onStateChange (connectAdvanced.js?4805:202)
    at dispatch (createStore.js?6413:173)
    at eval (index.js?e2e7:14)
    at dispatch (applyMiddleware.js?be0b:35)
    at Stream.handleResponse (index.js?710b:1)
    at Stream.EventEmitter.emit (events.js?bf30:96)
    at eval (fetch_request.js?30e8:83)
    at <anonymous>
divyanshu013 commented 6 years ago

Thanks for reporting this @davidklebanoff. Should be out in the next release šŸ»