Skip to main content

useEffect

The useEffect hook can be useful for running code that should run anytime the state of a widget changes or a widget is interacted with. You can use it to do data fetching when a component mounts (by using it with waitForTask ) or keeping state in sync between an iframe and the widget.

Signature

useEffect(effect: () => (() => void) | void): void

Parameters

ParameterDescription
effectA function that is executed whenever a widget's state is updated. If a function is returned by this function, the returned function will be called prior to running effects again.
info

Note: Because of How Widgets Run, this function should handle being called multiple times with the same state.

Remarks

There are three main use cases of useEffect:

Initializing network or plugin API-dependent widget state

Rendering code is synchronous and should only depend on widget state - if you wish to initialize widget state using information from the network (eg. HTTP requests in an iframe) or using information about the file (eg. using figma.currentPage.selection) - you can do this in useEffect. After the widget has rendered for the first time, any callback to useEffect is executed. Code in the function passed to useEffect is able to update widget state and perform asynchronous tasks (when paired with waitForTask).

Setting up figma.ui.onmessage handlers

You might have multiple calls to figma.showUI in various event handler (eg. onClick on various nodes or via usePropertyMenu actions) and want to consolidate message handling in one place. useEffect is a great place for this. Effects are guaranteed to have run before any event handler code is executed and after a widget re-renders (eg. in response to state changes).

info

Note: useEffect is called every time a widget's state is changed. This means that if you are setting up an event listener using figma.on you need to make sure that you remove the listener using figma.off in the function returned by your useEffect callback. figma.off not being called can lead to unexpected behavior where your code responds to an event multiple times.

useEffect event handler
const { widget } = figma
const { Text, useEffect } = widget

function EventHandlerExample() {
useEffect(() => {
const logSelection = () => {
console.log(figma.currentPage.selection)
}
figma.on('selectionchange', logSelection)
return () => figma.off('selectionchange', logSelection)
})

return <Text>Event handler example</Text>
}

widget.register(EventHandlerExample)

Consolidating state updating side-effects

Because useEffect callbacks are run whenever a widget state changes - they are good candidates for performing any side-effects. This is especially useful if you have multiple functions in your widget that might update a widget's state and you want to consistently trigger the same side-effects based the final widget's state.

Usage example

useEffect example
const { widget } = figma
const { Text, useEffect } = widget

function UseEffectExample() {
useEffect(() => {
console.log("useEffect callback called")
})

return <Text>useEffect example</Text>
}

widget.register(UseEffectExample)