recharts / recharts

Redefined chart library built with React and D3
http://recharts.org
MIT License
23.67k stars 1.69k forks source link

Cannot read properties of null (reading 'useContext') #4875

Closed JianyuZhan closed 1 month ago

JianyuZhan commented 1 month ago

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

I am trying the minimal rechart demo code, get the below error:

react.development.js:209 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

Something went wrong.
DetailsTypeError: Cannot read properties of null (reading 'useContext')

    at YAxis (http://localhost:3000/static/js/bundle.js:93362:22)
    at svg
    at Surface (http://localhost:3000/static/js/bundle.js:99271:24)
    at div
    at ChartLayoutContextProvider (http://localhost:3000/static/js/bundle.js:99367:28)
    at CategoricalChartWrapper (http://localhost:3000/static/js/bundle.js:95034:7)
    at div
    at ErrorBoundary (http://localhost:3000/static/js/bundle.js:136:5)
    at HealthEventsDashboard (http://localhost:3000/static/js/bundle.js:288:1)
    at RenderedRoute (http://localhost:3000/static/js/bundle.js:39787:5)
    at Routes (http://localhost:3000/static/js/bundle.js:40489:5)
    at div
    at div
    at Router (http://localhost:3000/static/js/bundle.js:40423:15)
    at BrowserRouter (http://localhost:3000/static/js/bundle.js:38364:5)
    at App

My code:

# HealthDashboard.js
import React, { PureComponent } from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts';
import ErrorBoundary from './ErrorBoundary';  

const data = [
  {
    name: 'Page A',
    uv: 4000,
    pv: 2400,
    amt: 2400,
  },
  {
    name: 'Page B',
    uv: 3000,
    pv: 1398,
    amt: 2210,
  },
  {
    name: 'Page C',
    uv: 2000,
    pv: 9800,
    amt: 2290,
  },
  {
    name: 'Page D',
    uv: 2780,
    pv: 3908,
    amt: 2000,
  },
  {
    name: 'Page E',
    uv: 1890,
    pv: 4800,
    amt: 2181,
  },
  {
    name: 'Page F',
    uv: 2390,
    pv: 3800,
    amt: 2500,
  },
  {
    name: 'Page G',
    uv: 3490,
    pv: 4300,
    amt: 2100,
  },
];

class HealthEventsDashboard extends PureComponent {
  render() {
    return (
      <ErrorBoundary>
        <div style={{ width: '100%', height: 400 }}>
          <LineChart
            width={500}
            height={300}
            data={data}
            margin={{
              top: 5,
              right: 30,
              left: 20,
              bottom: 5,
            }}
          >
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="name" />
            <YAxis />
            <Tooltip />
            <Legend />
            <Line type="monotone" dataKey="pv" stroke="#8884d8" activeDot={{ r: 8 }} />
            <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
          </LineChart>
        </div>
      </ErrorBoundary>
    );
  }
}

export default HealthEventsDashboard;

ErrorBoundary.js:

# ErrorBoundary.js
import React, { Component } from 'react';

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null, errorInfo: null };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    this.setState({ error, errorInfo });
    console.error("Error caught by ErrorBoundary:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return (
        <div>
          <h2>Something went wrong.</h2>
          <details style={{ whiteSpace: 'pre-wrap' }}>
            {this.state.error && this.state.error.toString()}
            <br />
            {this.state.errorInfo && this.state.errorInfo.componentStack
              ? this.state.errorInfo.componentStack
              : "No component stack available."}
          </details>
        </div>
      );
    }

    return this.props.children; 
  }
}

export default ErrorBoundary;

Demo 'App.js':

# App.js
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import HealthEventsDashboard from './components/HealthEventsDashboard'; 

const App = () => {

  return (
    <Router>
      <div>
        <div style={{ padding: 20 }}>
          <Routes>
            <Route path="/health_events" element={<HealthEventsDashboard />} />  {}
          </Routes>
        </div>
      </div>
    </Router>
  );
};

export default App;

Which versions of Recharts, and which browser / OS are affected by this issue? Did this work in previous versions of Recharts?

Ubuntu 22.04 Chrome Version 127.0.6533.89 (Official Build) (arm64) BTW, the 'npm start' in running on the remote machine(which runs Ubuntu 22.04), and I use Chrome on my local Macbook to access the UI

├── react-dom@18.3.1 ├── react-router-dom@6.26.0 ├── react-scripts@5.0.1 ├── react@18.3.1 ├── recharts@2.12.7

I've tried downgraded rechart version, but still got the same error.

ckifer commented 1 month ago

Hi - this doesn't seem to happen for anyone else. Can you make sure to delete your node_modules and package-lock file and re-install?

As the error says you may have mismatched versions of react

JianyuZhan commented 1 month ago

Hi - this doesn't seem to happen for anyone else. Can you make sure to delete your node_modules and package-lock file and re-install?

As the error says you may have mismatched versions of react

I've tried rm -rf node_modules then npm install but failed again, so I started from scratch to reinstall everything, it works now.