# UI panel with React \`useEffect\` hook can't call \`editDocument\`

**URL:** <https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872>\
**Category:** UXP Plugin API\
**Tags:** react, ui\
**Created:** [June 26, 2020, 2:49am UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872 "2020-06-26T02:49:06Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![abcd\_ca](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/abcd_ca/32/821_2.png) [@abcd\_ca](https://forums.creativeclouddeveloper.com/u/abcd_ca)\
**Post date:** [June 26, 2020, 2:49am UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/1 "2020-06-26T02:49:07Z")

</div>

I’m using React in my UI panel. Contemporary React uses [hooks](https://reactjs.org/docs/hooks-intro.html). The concept of the `useEffect` hook is that,

- actions like button clicks should set state
- the `useEffect` should process ‘side effects’ that you want to happen when it observes state changes.

In my case, I have a UI panel with buttons that allow me to modify the appearance of nodes in my document. Ex. if I click a button that should increase the font size, I click it, increment the state variable `fontSize` in my react component. Then, `useState` has `fontSize` as a dependency which triggers its function to run. Its function calls XD’s `editDocument` which then has a routine to apply the new text styles to the selection. When I do this though XD gives me an error, “[Error: Panel plugin edits must be initiated from a supported UI event]” (not directly because of this asynchronous paradigm that react has). I guess there’s no way around that?

---

<div class="post-metadata">

**Author:** ![pklaschka](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/pklaschka/32/3162_2.png) [@pklaschka](https://forums.creativeclouddeveloper.com/u/pklaschka)\
**Post date:** [June 26, 2020, 12:26pm UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/2 "2020-06-26T12:26:51Z")

</div>

While I’m not entirely sure about this (if someone achieved this, I’ll happily stand corrected), I believe you’re right: There isn’t a clean way around it.

In Panels, `editDocument` has to get called in the same tick as the user input event (or, in other words, as a direct result of an input event). As far as I understand it, `useEffect` gets triggered in an asynchronous fashion when the component “detects” it has to re-render. Therefore, the tick of the input event gets lost, making it impossible to use it to apply scenegraph edits.

On another note: It is only after re-reading the React docs after reading your question that I realized I should be using `useEffect` for a lot of things that I, until now, had handled directly in the input event handlers. Is there any real (noticeable) benefit in using `useEffect` for side effects (I’ve done this _wrong_ for quite a few also larger-scale personal React projects and haven’t had any problems with it…)

---

<div class="post-metadata">

**Author:** ![cpryland](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/cpryland/32/1172_2.png) [@cpryland](https://forums.creativeclouddeveloper.com/u/cpryland)\
**Post date:** [June 30, 2020, 5:30pm UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/3 "2020-06-30T17:30:57Z")

</div>

As @pklaschka says, there’s no way around actually doing the `editDocument()` work in your actual event handler.

But I think that’s a cleaner approach anyway, rather than doing it indirectly.

---

<div class="post-metadata">

**Author:** ![abcd\_ca](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/abcd_ca/32/821_2.png) [@abcd\_ca](https://forums.creativeclouddeveloper.com/u/abcd_ca)\
**Post date:** [July 6, 2020, 5:22pm UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/4 "2020-07-06T17:22:22Z")

</div>

Thanks for confirming the React/XD question. Regarding the React question about `useEffect`, I haven’t profiled the performance differences myself so I’m not sure but I know that by adhering to the prescribed way allows you to. 1. have input events store state differences using the `useState` hook. 2. use the `useEffect` hook to observe state changes and do stuff whenever state changes (which could change from various inputs so it also centralizes where your change handlers are). Note that you can use multiple `useEffect` hooks for different concerns in one component. The `useState` hook is asynchronous so you can’t rely on its value to be changed in the same tick. So for me, the `useEffect` hook is partly about avoiding race conditions too.

---

<div class="post-metadata">

**Author:** ![abcd\_ca](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/abcd_ca/32/821_2.png) [@abcd\_ca](https://forums.creativeclouddeveloper.com/u/abcd_ca)\
**Post date:** [July 6, 2020, 5:23pm UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/5 "2020-07-06T17:23:02Z")

</div>

Thank you for the confirmation.

---

<div class="post-metadata">

**Author:** ![cpryland](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/cpryland/32/1172_2.png) [@cpryland](https://forums.creativeclouddeveloper.com/u/cpryland)\
**Post date:** [July 6, 2020, 5:58pm UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/6 "2020-07-06T17:58:25Z")

</div>

That said, I have exactly the same need (to “debounce” some sliders before doing expensive document changes), so I may have to come up with some complex method for extending an async `editDocument()` process.

---

<div class="post-metadata">

**Author:** ![abcd\_ca](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/abcd_ca/32/821_2.png) [@abcd\_ca](https://forums.creativeclouddeveloper.com/u/abcd_ca)\
**Post date:** [July 7, 2020, 12:26am UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/7 "2020-07-07T00:26:35Z")

</div>

I gave up on debounce/throttle for this reason too. I’d be interested to find out if you come up with a way to do it. I was using a lodash/underscore implementation but I don’t think that is important.

---

<div class="post-metadata">

**Author:** ![cpryland](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/cpryland/32/1172_2.png) [@cpryland](https://forums.creativeclouddeveloper.com/u/cpryland)\
**Post date:** [July 7, 2020, 12:41am UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/8 "2020-07-07T00:41:35Z")

</div>

It wouldn’t be too hard, given an async `editDocument()`-called function. It can just await a promise that only fulfills when some input “settles down.”

Don’t know if I’ll get to it anytime soon, but I’ll certainly post here if I do.

---

<div class="post-metadata">

**Author:** ![pklaschka](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/pklaschka/32/3162_2.png) [@pklaschka](https://forums.creativeclouddeveloper.com/u/pklaschka)\
**Post date:** [July 7, 2020, 9:53am UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/9 "2020-07-07T09:53:19Z")

</div>

> [@cpryland](#):
>
> It wouldn’t be too hard, given an async `editDocument()` -called function. It can just await a promise that only fulfills when some input “settles down.”

Unfortunately, `editDocument()` locks the UI until resolved (cf. my comment at [Debouncing input events in panels - #7 by pklaschka](http://forums.creativeclouddeveloper.com/t/debouncing-input-events-in-panels/1170/7))…

---

<div class="post-metadata">

**Author:** ![cpryland](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/cpryland/32/1172_2.png) [@cpryland](https://forums.creativeclouddeveloper.com/u/cpryland)\
**Post date:** [July 7, 2020, 9:54am UTC](https://forums.creativeclouddeveloper.com/t/ui-panel-with-react-useeffect-hook-cant-call-editdocument/1872/10 "2020-07-07T09:54:45Z")

</div>

Interesting.

In my experience, if I sleep or do I/O from an async `editDocument()`-called function, the UI is updated.
