Merge pull request #1121 from sukarxn/feature/memoize-context-provider-values

perf: optimize ui components with react hooks memoization
This commit is contained in:
Rohan Verma 2026-04-05 13:26:20 -07:00 committed by GitHub
commit 4231efc076
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 22 additions and 13 deletions

View file

@ -158,14 +158,16 @@ export function PlateEditor({
// When not forced read-only, the user can toggle between editing/viewing. // When not forced read-only, the user can toggle between editing/viewing.
const canToggleMode = !readOnly; const canToggleMode = !readOnly;
const contextProviderValue = useMemo(()=> ({
onSave,
hasUnsavedChanges,
isSaving,
canToggleMode,
}), [onSave, hasUnsavedChanges, isSaving, canToggleMode]);
return ( return (
<EditorSaveContext.Provider <EditorSaveContext.Provider
value={{ value={contextProviderValue}
onSave,
hasUnsavedChanges,
isSaving,
canToggleMode,
}}
> >
<Plate <Plate
editor={editor} editor={editor}

View file

@ -7,6 +7,7 @@ import React, {
useCallback, useCallback,
useContext, useContext,
useEffect, useEffect,
useMemo,
useRef, useRef,
useState, useState,
} from "react"; } from "react";
@ -201,9 +202,9 @@ const Tabs = forwardRef<
}, },
[onValueChange, value] [onValueChange, value]
); );
const contextValue = useMemo(() => ({ activeValue, onValueChange: handleValueChange }), [activeValue, handleValueChange]);
return ( return (
<TabsContext.Provider value={{ activeValue, onValueChange: handleValueChange }}> <TabsContext.Provider value={contextValue}>
<div ref={ref} className={cn("tabs-container", className)} {...props}> <div ref={ref} className={cn("tabs-container", className)} {...props}>
{children} {children}
</div> </div>

View file

@ -5,6 +5,7 @@ import type { VariantProps } from "class-variance-authority";
import * as React from "react"; import * as React from "react";
import { toggleVariants } from "@/components/ui/toggle"; import { toggleVariants } from "@/components/ui/toggle";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useMemo } from "react";
const ToggleGroupContext = React.createContext< const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants> & { VariantProps<typeof toggleVariants> & {
@ -27,6 +28,8 @@ function ToggleGroup({
VariantProps<typeof toggleVariants> & { VariantProps<typeof toggleVariants> & {
spacing?: number; spacing?: number;
}) { }) {
const contextValue = useMemo(() => ({variant, size, spacing }), [variant, size, spacing]);
return ( return (
<ToggleGroupPrimitive.Root <ToggleGroupPrimitive.Root
data-slot="toggle-group" data-slot="toggle-group"
@ -40,7 +43,7 @@ function ToggleGroup({
)} )}
{...props} {...props}
> >
<ToggleGroupContext.Provider value={{ variant, size, spacing }}> <ToggleGroupContext.Provider value={contextValue}>
{children} {children}
</ToggleGroupContext.Provider> </ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root> </ToggleGroupPrimitive.Root>

View file

@ -1,12 +1,13 @@
"use client"; "use client";
import type React from "react"; import type React from "react";
import { createContext, useContext, useEffect, useState } from "react"; import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
import enMessages from "../messages/en.json"; import enMessages from "../messages/en.json";
import esMessages from "../messages/es.json"; import esMessages from "../messages/es.json";
import hiMessages from "../messages/hi.json"; import hiMessages from "../messages/hi.json";
import ptMessages from "../messages/pt.json"; import ptMessages from "../messages/pt.json";
import zhMessages from "../messages/zh.json"; import zhMessages from "../messages/zh.json";
import { set } from "zod";
type Locale = "en" | "es" | "pt" | "hi" | "zh"; type Locale = "en" | "es" | "pt" | "hi" | "zh";
@ -49,14 +50,14 @@ export function LocaleProvider({ children }: { children: React.ReactNode }) {
}, []); }, []);
// Update locale and persist to localStorage // Update locale and persist to localStorage
const setLocale = (newLocale: Locale) => { const setLocale = useCallback((newLocale: Locale) => {
setLocaleState(newLocale); setLocaleState(newLocale);
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
localStorage.setItem(LOCALE_STORAGE_KEY, newLocale); localStorage.setItem(LOCALE_STORAGE_KEY, newLocale);
// Update HTML lang attribute // Update HTML lang attribute
document.documentElement.lang = newLocale; document.documentElement.lang = newLocale;
} }
}; }, []);
// Set HTML lang attribute when locale changes // Set HTML lang attribute when locale changes
useEffect(() => { useEffect(() => {
@ -65,8 +66,10 @@ export function LocaleProvider({ children }: { children: React.ReactNode }) {
} }
}, [locale, mounted]); }, [locale, mounted]);
const contextValue = useMemo(() => ({ locale, messages, setLocale }), [locale, messages, setLocale]);
return ( return (
<LocaleContext.Provider value={{ locale, messages, setLocale }}> <LocaleContext.Provider value={contextValue}>
{children} {children}
</LocaleContext.Provider> </LocaleContext.Provider>
); );