3

I receive this error when I fetched the data for my chart (react-chartjs-2). I implement try/catch block and don't know how to remove this error. On Edge browser I get CRIPT28: SCRIPT28: Out of stack space

Uncaught (in promise) RangeError: Maximum call stack size exceeded
    at trackProperties (trackForMutations.js:16)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
    at trackProperties (trackForMutations.js:32)
Promise.catch (async)
(anonymous) @ ordersActions.js:44
(anonymous) @ index.js:9
(anonymous) @ index.js:43
(anonymous) @ index.js:55
(anonymous) @ bindActionCreators.js:5
loadDataForChart @ OrdersChart.js:96
boundFunc @ ReactErrorUtils.js:63
ReactErrorUtils.invokeGuardedCallback @ ReactErrorUtils.js:69
executeDispatch @ EventPluginUtils.js:83
executeDispatchesInOrder @ EventPluginUtils.js:106
executeDispatchesAndRelease @ EventPluginHub.js:41
executeDispatchesAndReleaseTopLevel @ EventPluginHub.js:52
forEachAccumulated @ forEachAccumulated.js:22
processEventQueue @ EventPluginHub.js:252
runEventQueueInBatch @ ReactEventEmitterMixin.js:15
handleTopLevel @ ReactEventEmitterMixin.js:25
handleTopLevelImpl @ ReactEventListener.js:70
perform @ Transaction.js:141
batchedUpdates @ ReactDefaultBatchingStrategy.js:60
batchedUpdates @ ReactUpdates.js:95
dispatchEvent @ ReactEventListener.js:145

Here's action I invoke in my component.

 export function getDataForChart(dtStart, dtEnd) {

      return function (dispatch) {
        let actionUrl = new Localization().getURL(baseUrl, 'GetDataForChart');
        dispatch({ type: types.CHARTSUMMARY });


        return axios.post(actionUrl, { dateStart: dtStart, dateEnd: dtEnd }, {
          headers: {
            'RequestVerificationToken': antiForgeryToken.value,
            'X-Requested-With': 'XMLHttpRequest'
          }
        }).then((response) => {
          dispatch({ type: types.CHARTSUMMARY_LOADED, payload: response.data })
        }).catch((error) => {
          dispatch({ type: types.CHARTSUMMARY_REJECTED, payload: error })

        })
      }
    }

Here's my component which is connected to redux store. It;seems to me that everythings fine.

    export class OrdersChart extends Component {
        constructor(props) {
            super(props)
            this.state = {
                eStart: moment(),
                eEnd: moment(),
                chartData: {},
                chartLoaded: false,
                chartStart: false
            }


            this.loadDataForChart = this.loadDataForChart.bind(this);
        }

        componentWillReceiveProps(nextProps) {
            const { chartData, chartLoaded, chartStart } = nextProps;
            if(this.state.chartData != chartData) {
                this.setState({ chartData, chartLoaded, chartStart })
            }
        }
        loadDataForChart() {
            this.props.actions.getDataForChart(this.state.eStart, this.state.eEnd);
        }

        render() {
            return (
                <div>
               /* Date pickers ...*/
          <BtnReload onClick={this.loadDataForChart}></BtnReload>
                  <Line data={this.state.chartData} options={{ tooltips: { mode: 'x' } }} />       
                </div>
            )
        }
    }

    function mapStateToProps(state) {
        return {
            chartData: state.chart.ChartData,
            chartLoaded: state.chart.chartLoaded,
            chartStart: state.chart.fetching
        }
    }

    function mapDispatchToProps(dispatch) {
        return {
            actions: bindActionCreators(Object.assign({}, ordersActions), dispatch)
        }
    }
    export default connect(mapStateToProps, mapDispatchToProps)(OrdersChart)
miuosh
  • 836
  • 3
  • 12
  • 35
  • How are you fetching your data? Please add some code to work with – Jimmy Surprenant Sep 20 '18 at 15:13
  • 2
    The error says: "Somewhere in your code, in the `render` or in a lifecycle method which updates the state, you use `setState` method or dispatch an action which updates your global state. This is why your component renders itself in a loop. – devserkan Sep 20 '18 at 15:17
  • Can you comment out `componentWillRecieveProps` method? – devserkan Sep 20 '18 at 15:37
  • When I comment componentWillReceiveProps the error does not show up. – miuosh Sep 20 '18 at 15:43
  • I console.log() some string to see how many times componentWillReceiveProps was invoked. It prints console.log statement tree times. – miuosh Sep 20 '18 at 15:50
  • what is version of react you are using . in latest versions its deprecated better to use methods like `getDerivedStateFromProps` and `componentDidUpdate` – aravind_reddy Sep 20 '18 at 15:53
  • It's react 15.6.2 and I can't upgrade it to v16 in this project. I used componentWillReceiveProps before without problems. Maybe it's something with the 'react-chartjs-2' library. – miuosh Sep 20 '18 at 16:01
  • in your componentWillRecieveProps did you try using `!==` instead of `!=` – aravind_reddy Sep 20 '18 at 16:29
  • @aravind_reddy Yes, I've tried :) – miuosh Sep 20 '18 at 16:30
  • so did the error disappear ? – aravind_reddy Sep 20 '18 at 16:31
  • No, It still appear :/ – miuosh Sep 20 '18 at 16:32
  • Are you trying to compare content of both objects? In that case, comparing with === or !== will end up comparing references. – Arnab Das Sep 20 '18 at 16:41
  • @ArnabDas Yes I've tried without success. I think the issue is `react-chartjs-2` library. I swap `` (which is library component) with new `` component. `TestProp` component only prints received data in browser (render divs with value). I don't get an error when I use TestProp component. – miuosh Sep 20 '18 at 16:56

3 Answers3

2

It's a little late but it's likely due to circular references in your state. Check this issue out: https://github.com/leoasis/redux-immutable-state-invariant/issues/15

According to the package's author (in a conversation from the link above):

What's the shape of your state? It looks like there may be circular dependencies in your state, which is causing problems with the way we traverse it to track mutations.

In order to fix this error, you can either remove the circular references in your state or configure the invariant middleware to ignore that branch of your state as follows, using object path syntax:

invariant({ ignore: ['path.to.ignore'] })
poroia
  • 45
  • 1
  • 10
  • 1
    Bonger, can you add some information about the solution mentioned in the linked page so this answer can be a standalone answer even if the link would be not accessible later. – Olcay Ertaş Feb 14 '20 at 06:42
1

the code that you paste here is incompetent but according to your error you are certainly causing a loop via your component so check wherever you are calling your methods repeatedly. in your code, I am suspicious you are changing your state and it used in your render method be aware of that whenever you change your state your component rendered

  • `componentWillReceiveProps(nextProps) { console.log('componentWillReceiveProps') const { chartData, chartLoaded, chartStart } = nextProps; if (!_.isEqual(nextProps.chartData, this.state.chartData) && chartLoaded) { console.log('setState') this.setState({ chartData }) } }` Above code prints 'setState' once so I think too many state updates is not the issue. – miuosh Sep 21 '18 at 09:50
  • 2
    `redux-immutable-state-invariant` library can cause the problem. I remove this middleware and error's gone. – miuosh Sep 21 '18 at 10:03
  • I think this article can be helpful. https://github.com/leoasis/redux-immutable-state-invariant – Alireza Yadegari Sep 21 '18 at 11:57
0

This is meant less as an answer, more as general help for this error.

I got this error by mishandling a Firebase response. I tried to merge it without transforming it. I'm using redux-actions to handle my state changes here. So I originally had:

[t.FIREBASE_SUCCESS]: (state, { payload }) => change(state, { $merge: payload }),

But what I needed was the extracted data object:

[t.FIREBASE_SUCCESS]: (state, { payload }) => change(state, { $merge: payload.data() }),

The payload.data() is the only change.

jmargolisvt
  • 5,722
  • 4
  • 29
  • 46