Jordan England-Nelson
Jordan England-Nelson

Reputation: 615

Pass props to componentDidMount() in React component

I'm trying to use a jQuery library (Highcharts) to render data in a React component.

From what I understand, I need to place the jQuery code inside the componentDidMount() function for it to run correctly. And it does, as long as I include static data inside of the componentDidMount() method.

But I want to hook the jQuery code up to my database so that the chart is reactive. I read that componentDidMount() only runs once, so I suspect I will have trouble placing reactive data inside it (I can't even get props to log to the console... they always come up undefined).

I'm able to pass props to componentDidUpdate(), but then my jQuery code doesn't display.

Anyone have a solution?

Thanks!!

Upvotes: 3

Views: 23041

Answers (2)

Saahil M
Saahil M

Reputation: 549

I could see you've two questions here. 1. How to pass context(this) of componentDidMount to the HighCharts function ? 2. Would it update every time there's any change in the props ?

  1. You could simply store the context in a variable and pass that context inside the Highcharts function which would give you that.props instead of checking the props with "this" eg.
class YourComponent extends React.Component {
    state = {
        chatData: []
    }
    componentDidMount () {
        let that = this;
        // Highcharts function () {
        // pass that.props
        // }
    }
}
  1. No, it won't be updated every time your props change.

    You could use getDerivedStateFromProps for this, and I would suggest, with some memoization.

// seed the state with props data
getDerivedStateFromProps (props, state) {
    // Check props data and state are same
    this.setState({chartsData: props.data});
}

Or you could directly seed the state or if you don't even need to set the state, just pass the props directly to the function.


state = {chartData: this.props.data};


render () {
    // Highcharts function () {
    // pass this.props or this.state
    // }
}

You shouldn't declare a function inside render as it makes a new copy of it every time the component renders but in this case, you need to change the state or data every time the props change.

Upvotes: 1

Fabian Schultz
Fabian Schultz

Reputation: 18546

You can utilize the .setData methods that Highcharts provides. You can update the data every time you receive new props. Here's a very basic example showing this:

class Chart extends React.Component {
  constructor() {
    super();
    // Init state.
    this.state = { chart: {} };
  }
  componentDidMount() {
    const _this = this;
    // Init chart with data from props.
    var chart = Highcharts.chart('chart', {
      series: [{ data: _this.props.data }]
    });
    // Save the chart "container" in the state so we can access it from anywhere.
    this.setState({ chart });
  }
  componentWillReceiveProps(props) {
    // Update the chart with new data every time we receive props.
    this.state.chart.series[0].setData(props.data);
  }
  render() {
    return <div id="chart" />;
  }
}

class App extends React.Component {
  constructor() {
    super();
    // Set some initial data.
    this.state = { data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]};
    this.changeData = this.changeData.bind(this);
  }
  changeData() {
    // Update with a different dataset.
    this.setState({
      data: [129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4],
    });
  }
  render() {
    return(
      <div>
        <button onClick={this.changeData}>Change Data</button>
        <Chart data={this.state.data} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('View'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="View"></div>

Upvotes: 8

Related Questions