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
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.
First of all we import sketch, which is like the heart of the Sketch API.
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.
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
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.
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.
That’s it! Now the React UI will be updated whenever a user changes selection!
Scenario 3 — Watch out for the dinosaur!
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)
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!