# Update react component without re-rendering entire element

**URL:** https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106
**Category:** Help
**Created:** [August 17, 2018, 6:33pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106 "2018-08-17T18:33:46Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [August 17, 2018, 6:33pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/1 "2018-08-17T18:33:46Z")

</div>

I want to prototype some charts from [http://nivo.rocks](http://nivo.rocks). I have some success (after reading through the docs and Mike’s recent post on jsx) but can’t figure out how to provoke React to update the chart when the data changes rather than re-render the entire chart.

Here’s what I have now:

> **[Nivo React Components / Observable](https://beta.observablehq.com/d/54f8ea4f38dbc4ad)**
>
> A better way to code.

If you “roll the dice” with [http://nivo.rocks/chord](http://nivo.rocks/chord) you’ll see nice transitions. But in my notebook, if you update the data manually, it appears that the entire svg element is getting re-rendered (which is expected, but not desired).

I’ve tried to prefix the data parameter with mutable to prevent re-rendering, but that doesn’t seem to work.

---

<div class="post-metadata">

### Author: ![tom](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/tom/32/2262_2.png) [@tom](https://talk.observablehq.com/u/tom)
#### Post date: [August 31, 2018, 11:27pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/2 "2018-08-31T23:27:17Z")

</div>

Hey, sure - here’s an example: [https://beta.observablehq.com/d/8700eeab71f938c5](https://beta.observablehq.com/d/8700eeab71f938c5)

I’ve added some notes to the notebook about what the essential differences are: the main thing is that it uses a consistent `div` as the render target, instead of recreating a `div` on each render.

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 1, 2018, 12:13am UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/3 "2018-09-01T00:13:03Z")

</div>

Thanks Tom – this is the example I was looking for. I had actually come to the same conclusion – that I was clobbering the save `div` but hadn’t had time to circle back and try it out. Many thanks!

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 4, 2018, 3:46pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/4 "2018-09-04T15:46:56Z")

</div>

@tom Is there a way (or what is the best way) to abstract the long string between the `` into a variable?

e.g.  
`<Chord width={height} height={width} matrix={chord_data} keys={[...`

I want to separate the long specs (of which I will have several) to be able to reuse the chart generation instructions.

I tried doing this (naively) by creating a cell called chart\_specs = `<Chord...` and then calling  
ReactDOM.render(jsx({ Chord, chord\_data, chord\_spec, height: 400, width })chart\_specs, circle)  
But that didn’t seem to work.

Thanks.

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 4, 2018, 4:19pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/5 "2018-09-04T16:19:11Z")

</div>

Also, the Responsive elements don’t seem to work e.g. if you change `<Chord...` to `<ResponsiveChord...` I’m guessing because they are expecting context?

---

<div class="post-metadata">

### Author: ![bgchen](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/bgchen/32/784_2.png) [@bgchen](https://talk.observablehq.com/u/bgchen)
#### Post date: [September 4, 2018, 9:21pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/6 "2018-09-04T21:21:07Z")

</div>

I don’t know how to answer the rest of your question, but note that you need another set of parentheses when passing `chart_specs` to `jsx`. Try:

`jsx({ Chord, chord_data, chord_spec, height: 400, width })(chart_specs)`

(note that `jsx(stuff)` returns a function, so you need to pass it `chart_specs` as an argument).

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 5, 2018, 3:20pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/7 "2018-09-05T15:20:59Z")

</div>

@bgchen Thanks for the tip. I tried that approach but it didn’t work for me. In the end the following worked

`linex = ReactDOM.render(jsx({ ResponsiveLine, line_data, line_specs, height: 400, width: 900 })'${line_specs}', line_dom)`  
Note: The single quotes around `${line_specs}` are supposed to be template ` delimiters, but I can’t figure out how to escape them here.

I also resolved the ResonsiveLine issue – you need to make sure your target div has a **height** style property defined or it won’t render (see nivo docs).

I used `line_dom = html'<div style="height: 400px; width: 100%;" />'`

Which seems to work.

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 5, 2018, 7:00pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/8 "2018-09-05T19:00:33Z")

</div>

> **[Nivo React Components](https://beta.observablehq.com/@john-clarke/nivo-react-components)**
>
> An Observable notebook by John Clarke.

---

<div class="post-metadata">

### Author: ![RandomFractals](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/randomfractals/32/759_2.png) [@RandomFractals](https://talk.observablehq.com/u/RandomFractals)
#### Post date: [September 5, 2018, 8:13pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/9 "2018-09-05T20:13:56Z")

</div>

still broke on my end:

> **[Nivo React Components](https://observablehq.com/@john-clarke/nivo-react-components)**
>
> An Observable notebook by John Clarke.

just comes up nivo blank:

 ![nivo-blank](https://canada1.discourse-cdn.com/flex030/uploads/observablehq/original/1X/3784be7d031e49a19bfd3f2e0b10d67f11f6321b.png)

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 5, 2018, 8:44pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/10 "2018-09-05T20:44:48Z")

</div>

Thanks @RandomFractals – I think something broke with importing `ReactDOM = r('react-dom')` since @tom looked at this earlier. Could it be an issue with how Observable imports?

I looked up react-dom with `https://beta.observablehq.com/@tmcw/module-require-debugger` and it came back with `require('react-dom@16.4.2/index.js').catch(() => window.checkDCE)` but I couldn’t get that to work.

@tom any ideas?

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 5, 2018, 8:51pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/11 "2018-09-05T20:51:06Z")

</div>

@RandomFractals The following seems to fix the issue:  
`ReactDOM = require('https://wzrd.in/standalone/react-dom@latest')`

---

<div class="post-metadata">

### Author: ![RandomFractals](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/randomfractals/32/759_2.png) [@RandomFractals](https://talk.observablehq.com/u/RandomFractals)
#### Post date: [September 5, 2018, 8:53pm UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/12 "2018-09-05T20:53:08Z")

</div>

now we talking 🙂

cool chord diagram!

 ![nivo-works](https://canada1.discourse-cdn.com/flex030/uploads/observablehq/original/1X/9d5bffbd6049a9189d15d420a6cbe711cf8b5687.png)

---

<div class="post-metadata">

### Author: ![bgchen](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/bgchen/32/784_2.png) [@bgchen](https://talk.observablehq.com/u/bgchen)
#### Post date: [September 6, 2018, 12:34am UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/13 "2018-09-06T00:34:11Z")

</div>

I’m glad you were able to get it to work! Note that two of the user links in your first paragraph are broken due to a missing “/” (also, note that my observable link is (confusingly) [@bryangingechen](https://observablehq.com/@bryangingechen), not that I really contributed enough to be acknowledged so kindly!).

As it turns out, my advice didn’t work because of a bug in my understanding of template literals. I had thought (incorrectly) that

`someFunction(stuff)`some template string``

was equivalent to

`spec = `some template string`; someFunction(stuff)(spec)`,

but in fact tag functions are a bit more complicated in general. As usual, reading [the relevant web docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates) was enlightening. In short, your solution seems like the right one to me too.

By the way, to include backticks in markdown, just use multiple backticks as delimiters, [here’s the discussion in the markdown syntax](https://daringfireball.net/projects/markdown/syntax#code).

---

<div class="post-metadata">

### Author: ![john-clarke](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/john-clarke/32/219_2.png) [@john-clarke](https://talk.observablehq.com/u/john-clarke)
#### Post date: [September 6, 2018, 1:16am UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/14 "2018-09-06T01:16:11Z")

</div>

@bgchen Thanks for the follow-up. I had to update the reference to ReactDOM once again as it was failing again. Links are corrected. [https://beta.observablehq.com/@john-clarke/nivo-react-components](https://beta.observablehq.com/@john-clarke/nivo-react-components)

---

<div class="post-metadata">

### Author: ![bgchen](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/bgchen/32/784_2.png) [@bgchen](https://talk.observablehq.com/u/bgchen)
#### Post date: [September 6, 2018, 1:48am UTC](https://talk.observablehq.com/t/update-react-component-without-re-rendering-entire-element/1106/15 "2018-09-06T01:48:31Z")

</div>

Yeah, unfortunately, issues with unpkg (which `require` uses by default), wzrd.in, and bundle.run are all too frequent. There’s another thread about them [here](https://talk.observablehq.com/t/bundle-run-errors-breaking-notebooks/1050), with no solution, sadly.
