How to use React in your Sketch plugin – Part II

In this tutorial I’ll teach you how to communicate between Sketch and a React UI

Fredrik Ward
Design + Sketch
6 min readJul 27, 2020

--

This is part two of my tutorial series on How to use React in a Sketch plugin.

In part one we created a Sketch plugin that rendered a React UI in a WebView. The React UI ”only” displayed the text ”React says hello!”. It didn’t communicate with the Sketch document at all…

This is what we’re going to implement in this tutorial! 👨🏻‍💻

If you haven’t read part one yet: Please do. This tutorial will make a lot more sense if you know what went on in part one.

If you don’t have the patience or the time to read through my entire tutorial you can find a GitHub repo containing the plugin we are going to build here.

Our starting point

Our starting point will be the plugin we created in part one. You can download or clone it from this GitHub repo.

Let’s get started!

The three scenarios of communication

We need to consider the following three communication scenarios when using React as our plugin’s UI:

  • Send initial data to the React UI when the plugin starts/executes
  • A user’s actions (like changing selection, saving etc.) should trigger data to be sent to the React UI
  • You should be able to send data from the React UI to the Sketch API (which in turn modifies your Sketch document)

Scenario 1 — Send initial data to the React UI when the plugin starts/executes

In this example we send the current selections name to the React UI.

Add this at the top of src/my-command.js

First of all we import sketch, which is like the heart of the Sketch API.

Change existing did-finish-load into this in src/my-command.js

We’ll add an event handler on webContents. WebContents is responsible for rendering and controlling the webpage in the WebView. It will listen for the event did-finish-load. This event (did-finish-load) is emitted when everything has finished loading in the WebView. This includes our React UI. So in the callback function of the event handler we can safely assume that our React UI is ready to receive data! 🥳

We retrieve the selection’s name by using the Sketch API (You can find the Sketch API’s reference docs here).

We then include the name as a part of the input and call the function executeJavaScript.

ExecuteJavaScript executes (evaluates) its input as JavaScript on the webpage inside our WebView.

Now we need to define the function that gets called on the webpage inside our WebView by executeJavaScript: sendData.

Add this at the very bottom of resources/webview.js

The function sendData creates a CustomEvent named send-data to which it adds our data (Sketch selection name). The event send-data is then dispatched on the window object. This is what our React UI will be listening to.

We could rewrite our App component to use event listening React hooks. This was my initial approach. However, I changed my mind and instead I’ll be rewriting our App component so it becomes a class component. My reason for doing so is because I need the class’ lifecycle hooks for various other functionality (out-of-scope for this tutorial).

Update April 30 — 2021

I’ve written a React hook example that handles the data communication. It is part three of this series: How to use React in your Sketch plugin — With React Hooks

Replace everything in resources/components/App.jsx with the following code

We add an event listener to our window object when our App component has been added to the DOM (componentDidMount). This event listener listens to our event send-data.

We then define the function we want to be called when our event send-data is dispatched. We call it handleSendDataEvent and it updates the App component’s state. And voilà! The data (Sketch selection name) is now available in our React UI!

Scenario 2 — A user’s actions should trigger data to be sent to the React UI

To achieve this, we’re going to listen to a Sketch plugin action. There are a lot of actions available, but the one we’re going to listen to is SelectionChanged. This action occurs when a user changes selection.

Add row 13 to “actions” in src/manifest.json

From the Sketch Developer portal:

Some actions (like SelectionChanged) actually happen in two phases: begin and finish. If you want to call a function only on one of them, you can add a handler for SelectionChanged.begin, or SelectionChanged.finish. If you don’t add anything, the action will be triggered twice.

We only want to trigger a React UI update once (with the new data/selection). So we’ll use the action SelectionChanged.finish to trigger the function onSelectionChange (line 13 above).

Now we need to define the function onSelectionChange.

Add this at the bottom of src/my-commands.js

That’s it! Now the React UI will be updated whenever a user changes selection!

Scenario 3 — Watch out for the dinosaur!

Replace everything in resources/components/App.jsx with the following code

We add a button to which we connect a click handler. We call this function handleButtonClick. This function does two things:

  • Emits an event (which will be handled by webContents) called setSelectionName using window.postMessage. This event contains the new selection name.
  • Updates React UI’s state with the new name. This is needed since the call to postMessage technically has nothing to do with our React UI. (I haven’t tested this, but you should be able to connect an action, like TextChanged, on your Sketch document to trigger a React UI update)
Add this to your default export in src/my-command.js

Here we’re setting up our event handler for our postMessage call setSelectionName. In its callback function we set the new selection name.

That’s it! ✅

Troubleshooting

Sketch’s official documentation about debugging a plugin is a good place to start.

FYI: The ”commands” stated in the different help sections are to be run in the Terminal App.

This plugin has already been linked

If you see “This plugin has already been linked” when you run “npm install” in the project you cloned or downloaded you need to remove this link and install again otherwise it might point to the wrong plugin and the changes you make will not reflect in Sketch.

How to remove an already existing plugin/link

Open Sketch’s plugin folder:

/Users/[Your username]/Library/Application Support/com.bohemiancoding.sketch3/Plugins

Remove the already existing plugin/link.

Run “npm install” again in your project folder. The Sketch plugin’s last modified date should be updated. If it’s not: remove the plugin-file and install again.

Complete example

You can find a complete plugin example here. In this repo I’ve removed the boilerplate button and it’s corresponding functionality.

Summary

In this tutorial I’ve taught you how to communicate between Sketch and a React UI. We have covered the follow scenarios:

  • Send initial data to the React UI when the plugin starts/executes
  • A user’s actions triggers data to be sent to the React UI
  • Sending data from the React UI to the Sketch API (which in turn modifies your Sketch document)

Use this as a starting point and create your own magical 🔮🎩 plugins 🔌

I’ll write more tutorials on this topic as I progress with my plugin development.

Thanks for reading!

--

--

Fredrik Ward
Design + Sketch

Co-founder and developer of Sketch2React/Stratos Tokens/Marcode