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
Project Setup
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.
Configuring Puck
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:
- A Dashboard component that greets users and contains a DropZone for nesting other components
- An ArticleList component that displays a list of articles inside the Dashboard
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.
Adding Context
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:
-
Accessing data stored outside Puck: We’ll begin by setting up a context containing a logged-in user’s data outside of the
component, and then access it from within Puck components. - Passing data to a nested component: Next, we’ll set up a search query context within the Dashboard. This will allow us to capture a user’s search query, store it in the context, and pass it down to the ArticleList component. The goal is to filter the list of articles based on the user’s query, demonstrating how to pass data between a parent and child Puck component.
Step 1: Define the Context outside 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
Step 2: Create the Context Provider outside Puck
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
Step 3: Integrate the Provider with Puck
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
Step 4: Consume the Context in the Puck Components
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
Step 7: Consume the Context from Puck components
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 of using React Context
✅ Pros:
- Provides a robust solution for sharing state across components, both inside and outside Puck
- Integrates seamlessly with existing React patterns and components
- Can handle complex logic and state
- Zero external dependencies as React Context comes with React
❌ Cons:
- Performance can degrade if you frequently update state at the top of a large component tree, as every subscriber needs to re-render
- When managing multiple context providers, things can become harder to debug
Taking it further
There are a bunch of ways in which you can improve managing shared state in Puck depending on the complexity of your editor:
- Optimize context usage - If you notice performance issues or unnecessary re-renders, consider splitting your context into smaller, more focused contexts. This allows components to subscribe only to the parts of the state they need, minimizing re-renders.
- Incorporate state libraries - If you have multiple shared states and more complex logic, you could move beyond React Context and use your favorite state library. Whether it’s Redux, Zustand, or another library your project is already using, these can simplify managing complex state and improve rendering performance.
- Leverage server-side state - If your application relies heavily on data fetched from a server, consider using a library like TanStack Query or SWR. These libraries manage caching, re-fetching, and synchronization for you, reducing the need for complex shared client-side state.
Your Turn to Build Smarter with Puck ?
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:
- ? Star Puck on GitHub to show your support and inspire others to explore.
- ? Join our Discord community to connect, learn, and collaborate.
- ? Follow us on X and Bluesky for sneak peeks, updates, and tips.
- ? Explore the documentation for advanced techniques to supercharge your builds.
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!

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

The differences in performance and efficiency between Python and JavaScript are mainly reflected in: 1) As an interpreted language, Python runs slowly but has high development efficiency and is suitable for rapid prototype development; 2) JavaScript is limited to single thread in the browser, but multi-threading and asynchronous I/O can be used to improve performance in Node.js, and both have advantages in actual projects.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Dreamweaver Mac version
Visual web development tools

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Dreamweaver CS6
Visual web development tools

SublimeText3 Linux new version
SublimeText3 Linux latest version

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.
