Home >Web Front-end >JS Tutorial >Managing application state in Puck
Puck is the open-source visual editor for React, empowering the next generation of page builders and no-code products. Give us a star on GitHub! ⭐️
Puck has been rapidly growing, and it’s been awesome to watch! ? Developers from all backgrounds are pushing the boundaries of what this open-source visual editor can do. But as more people dive into Puck, one question keeps coming up in our Discord community:
“How can I pass data or share state between components in Puck?”
In other words: how do you make one component react to changes in another? For example, you might create a DropZone component with a search input, so that any lists dropped inside it can read its value:
At first, Puck’s built-in magic might make you think it handles state in a unique way. But here’s the thing: Puck is just React—and so are the components you pass into it. That means that you can rely on any state library or tool you would normally use to manage and share data between components. For this article, I’ll keep it simple and teach you how to solve this problem by using Context.
Before we get started: I’ll assume you’ve got a basic understanding of Puck and how it works. If you’re new here, that’s totally fine—you’re welcome to follow along! But I’d recommend checking out the getting started guide first to get familiar with the basics
To make things easy, I’ve prepared a basic React project on GitHub with Puck pre-installed and ready to go. Clone and install it by running the following commands in your terminal:
git clone https://github.com/FedericoBonel/basic-puck-app cd ./basic-puck-app npm install
Already working on an existing project? No problem at all! You can simply install Puck as a dependency with NPM:
npm i @measured/puck --save
And if you’re using frameworks like Next.js or Remix, Puck offers official recipes to make the setup process seamless.
For this tutorial, I’ll assume you’ve cloned the GitHub repo to keep things straightforward. That said, the concepts and steps will apply to any setup—just update the file names as needed to fit your project’s structure.
With your project ready to go, the next step is to configure Puck. Open the src/App.jsx file and swap its contents with the code below. This will set up Puck with a basic config for dragging and dropping two components:
git clone https://github.com/FedericoBonel/basic-puck-app cd ./basic-puck-app npm install
Great! Your basic setup is now complete. Next, let’s dive into adding shared state to your editor.
React Context is the perfect solution for our problem because it offers a simple way to share and manage data across all your components—both inside and outside the editor. It creates a "global state" that you can access whenever needed, making it ideal for scenarios where you need to pull in data from outside Puck—like the selected theme or the logged-in user—or share data between Puck components.
In this guide, I’ll walk you through two common use cases for React Context within Puck:
Setting up context in Puck follows the same pattern as any React app. You create a Context provider to define and manage your shared state, wrap it around a parent component, and access or update the state wherever it's required in your app.
Start by creating a new Context for the user data. This Context will include both the user object and a function to update the user state.
npm i @measured/puck --save
Next, create a UserProvider component that will wrap your Puck editor. This provider will manage the user state and make it available to all children.
For the sake of brevity, I’m using a dummy user and the setter function returned by useState.
// App.jsx import { Puck, DropZone } from "@measured/puck"; import "@measured/puck/puck.css"; // The configs for your draggable components // Ideally you would pull these out into their own files const dashboardConfig = { render: () => { return ( <div > <p>Once you’ve updated the file, start the application in development mode, and navigate to http://localhost:5173 to verify everything is working as expected:<br> </p> <pre class="brush:php;toolbar:false">npm run dev
To integrate the provider with your Puck editor, simply wrap the editor with the UserProvider. You can put the UserProvider anywhere above the editor in your component tree (like in your index file), and it'll work just fine. Once you've done that, all your editor components will have access to the context!
git clone https://github.com/FedericoBonel/basic-puck-app cd ./basic-puck-app npm install
Now you can access the UserContext in any of your Puck components. Following our use case example, let’s update the Dashboard component so that it displays a “welcome back” message for logged-in users and a “generic welcome” message for guests.
npm i @measured/puck --save
Now, we’ll read the context in the components that are dropped inside the context provider. In our case, we’ll consume the context in the ArticleList component, which the user has nested inside the Dashboard via the DropZone. This allows the ArticleList to respond to changes in the search query and update accordingly.
// App.jsx import { Puck, DropZone } from "@measured/puck"; import "@measured/puck/puck.css"; // The configs for your draggable components // Ideally you would pull these out into their own files const dashboardConfig = { render: () => { return ( <div > <p>Once you’ve updated the file, start the application in development mode, and navigate to http://localhost:5173 to verify everything is working as expected:<br> </p> <pre class="brush:php;toolbar:false">npm run dev
If you now head into the editor, drag a Dashboard component onto the canvas, drop an ArticleList inside it, and modify the initialQuery field, you’ll see the list dynamically filter the articles based on the query. ?
You could even expand this setup by having multiple list components with different content reuse the same query context.
? And that’s it! You now have shared state between nested Puck components. ?
✅ Pros:
❌ Cons:
There are a bunch of ways in which you can improve managing shared state in Puck depending on the complexity of your editor:
Taking shared state management in Puck to the next level unlocks a world of possibilities for building dynamic, reactive page builders. I’m excited to see the unique and powerful apps you’ll build using these strategies.
So, if this article has inspired you to build something, you have a question about Puck or you want to contribute, here’s how you can get involved:
The future of Puck—and no-code innovation—is in your hands. Start building today, and let’s redefine what’s possible together! ?
The above is the detailed content of Managing application state in Puck. For more information, please follow other related articles on the PHP Chinese website!