Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
magicui-hooks
Advanced tools
This package provides a collection of useful React hooks and utilities for building UI components.
By destructuring isMobile
, isTablet
, and isDesktop
from the useMediaQuery hook
, you have more flexibility in rendering different content or applying different styles based on the specific breakpoint.
import React from "react";
import { useMediaQuery } from "magicui-helpers";
const ResponsiveLayout: React.FC = () => {
const { isMobile, isTablet, isDesktop } = useMediaQuery();
return (
<div>
{isMobile && (
<div className="mobile-layout">
<h1>Mobile Layout</h1>
</div>
)}
{isTablet && (
<div className="tablet-layout">
<h1>Tablet Layout</h1>
</div>
)}
{isDesktop && (
<div className="desktop-layout">
<h1>Desktop Layout</h1>
</div>
)}
</div>
);
};
export default ResponsiveLayout;
By using the useViewport hook, you can easily access the current viewport dimensions and adapt your component's rendering or behavior based on the viewport size. This is particularly useful for creating responsive layouts or making decisions based on the available screen space.
import React from "react";
import { useViewport } from "magicui-helpers";
const ResponsiveComponent: React.FC = () => {
const { width, height } = useViewport();
return (
<div>
<h1>Viewport Dimensions</h1>
<p>Width: {width}px</p>
<p>Height: {height}px</p>
{/* Render content based on viewport dimensions */}
{width < 600 && (
<div>
<h2>Mobile Content</h2>
{/* Mobile-specific content */}
</div>
)}
{width >= 600 && width < 1200 && (
<div>
<h2>Tablet Content</h2>
{/* Tablet-specific content */}
</div>
)}
{width >= 1200 && (
<div>
<h2>Desktop Content</h2>
{/* Desktop-specific content */}
</div>
)}
</div>
);
};
export default ResponsiveComponent;
The useControlledForm hook provides a simple and reusable way to manage form state and handle form submissions. It abstracts away the repetitive form management logic and allows you to focus on the form's specific requirements.
import React from "react";
import { useControlledForm } from "magicui-helpers";
const LoginForm: React.FC = () => {
const { values, errors, isSubmitting, handleChange, handleSubmit } =
useControlledForm(
{
email: "",
password: "",
},
(values) => {
console.log(values);
}
);
return (
<form onSubmit={handleSubmit}>
<div>
<label>Email:</label>
<input
type="email"
name="email"
value={values.email}
onChange={handleChange}
/>
{errors.email && <span>{errors.email}</span>}
</div>
<div>
<label>Password:</label>
<input
type="password"
name="password"
value={values.password}
onChange={handleChange}
/>
{errors.password && <span>{errors.password}</span>}
</div>
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? "Logging in..." : "Log In"}
</button>
</form>
);
};
export default LoginForm;
The useDebounce hook, we ensure that the search is triggered only after the user has stopped typing for 500 milliseconds. This helps optimize performance by avoiding excessive searches while the user is still typing.
import React, { useState } from "react";
import { useDebounce } from "magicui-helpers";
const SearchInput: React.FC = () => {
const [searchTerm, setSearchTerm] = useState("");
const debouncedSearchTerm = useDebounce(searchTerm, 500);
const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchTerm(event.target.value);
};
// Use the debounced search term to trigger the search
useEffect(() => {
// Perform the search with the debounced search term
console.log("Searching for:", debouncedSearchTerm);
}, [debouncedSearchTerm]);
return (
<div>
<input
type="text"
value={searchTerm}
onChange={handleSearch}
placeholder="Search..."
/>
</div>
);
};
export default SearchInput;
The useDebounceEffect hook is extremely useful in scenarios where you want to delay the execution of an effect based on rapidly changing values, such as search inputs, filtering, or auto-saving of form data. It helps optimize performance by reducing the number of unnecessary effect executions.
import React, { useState } from "react";
import { useDebounceEffect } from "magicui-helpers";
const SearchInput: React.FC = () => {
const [searchTerm, setSearchTerm] = useState("");
useDebounceEffect(
() => {
// Perform the search with the debounced search term
console.log("Searching for:", searchTerm);
},
[searchTerm],
500
);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchTerm(event.target.value);
};
return (
<div>
<input
type="text"
value={searchTerm}
onChange={handleChange}
placeholder="Search..."
/>
</div>
);
};
export default SearchInput;
The useEffectOnce hook
, we ensure that the API request to fetch user data is made only once when the component mounts. This prevents unnecessary re-fetching of data on subsequent re-renders of the component.
import React, { useState } from "react";
import { useEffectOnce } from "magicui-helpers";
interface User {
id: number;
name: string;
email: string;
}
const UserProfile: React.FC = () => {
const [user, setUser] = (useState < User) | (null > null);
const [loading, setLoading] = useState(true);
const [error, setError] = (useState < string) | (null > null);
useEffectOnce(() => {
const fetchUser = async () => {
try {
const response = await fetch("https://api.example.com/user");
if (!response.ok) {
throw new Error("Failed to fetch user");
}
const data: User = await response.json();
setUser(data);
setLoading(false);
} catch (error) {
setError("An error occurred while fetching user data");
setLoading(false);
}
};
fetchUser();
});
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
if (!user) {
return null;
}
return (
<div>
<h2>User Profile</h2>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
);
};
export default UserProfile;
The useLocalStorage hook, you can easily persist data across sessions and restore it when the user revisits your application. This is particularly useful for storing user preferences, settings, or any other data that needs to be remembered between visits.
import React from "react";
import { useLocalStorage } from "magicui-helpers";
const Settings: React.FC = () => {
const [theme, setTheme] = useLocalStorage < string > ("theme", "light");
const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light");
};
return (
<div>
<h1>Settings</h1>
<p>Current theme: {theme}</p>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
};
export default Settings;
useOnClickOutside
hook takes two arguments: ref (a reference to the element you want to detect clicks outside of) and handler (the callback function to be executed when a click outside the element is detected).mousedown
and touchstart
events on the document.import React, { useRef, useState } from "react";
import { useOnClickOutside } from "magicui-helpers";
const Modal: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const modalRef = useRef < HTMLDivElement > null;
const openModal = () => {
setIsOpen(true);
};
const closeModal = () => {
setIsOpen(false);
};
useOnClickOutside(modalRef, closeModal);
return (
<div>
<button onClick={openModal}>Open Modal</button>
{isOpen && (
<div ref={modalRef} className="modal">
<div className="modal-content">
<h2>Modal Title</h2>
<p>Modal content goes here...</p>
<button onClick={closeModal}>Close</button>
</div>
</div>
)}
</div>
);
};
export default Modal;
import React from 'react';
import {useBreakpoints} from 'magicui-helpers';
const ResponsiveLayout: React.FC = () => {
const breakpoints = useBreakpoints();
return (
<div>
{breakpoints.xs && (
<div>
<h1>Extra Small Screen</h1>
{/* Content for extra small screens */}
</div>
)}
{breakpoints.sm && (
<div>
<h1>Small Screen</h1>
{/* Content for small screens */}
</div>
)}
{breakpoints.md && (
<div>
<h1>Medium Screen</h1>
{/* Content for medium screens */}
</div>
)}
{breakpoints.lg && (
<div>
<h1>Large Screen</h1>
{/* Content for large screens */}
</div>
)}
{breakpoints.xl && (
<div>
<h1>Extra Large Screen</h1>
{/* Content for extra large screens */}
</div>
)}
</div>
);
};
export default ResponsiveLayout;```
The useIntersectionObserver
hook, you can efficiently load images or other content only when they are in view, improving performance and user experience. This hook is particularly useful for implementing lazy loading, infinite scrolling, or triggering animations when elements become visible.
import React from "react";
import { useIntersectionObserver } from "magicui-helpers";
interface LazyLoadImageProps {
src: string;
alt: string;
}
const LazyLoadImage: React.FC<LazyLoadImageProps> = ({ src, alt }) => {
const [elementRef, isIntersecting] = useIntersectionObserver({
rootMargin: "0px 0px 100px 0px",
});
return (
<div ref={elementRef}>
{isIntersecting ? (
<img src={src} alt={alt} />
) : (
<div
style={{ width: "100%", height: "200px", backgroundColor: "#f0f0f0" }}
/>
)}
</div>
);
};
export default LazyLoadImage;
The useFormValidation
hook provides a powerful and flexible way to handle form validation in React. It abstracts away the validation logic and provides a clean and reusable interface for managing form fields and their validation states.
import React from "react";
import { useFormValidation } from "magicui-helpers";
const SignupForm: React.FC = () => {
const { formFields, getFieldProps, isFormValid } = useFormValidation(
{
name: "",
email: "",
password: "",
},
{
name: { required: true, minLength: 2 },
email: { required: true, pattern: /^\S+@\S+$/i },
password: { required: true, minLength: 6 },
}
);
const handleSubmit = (event: React.FormEvent) => {
event.preventDefault();
if (isFormValid()) {
// Submit the form data
console.log(formFields);
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Name:</label>
<input type="text" {...getFieldProps("name")} />
{formFields.name.error && <span>{formFields.name.error}</span>}
</div>
<div>
<label>Email:</label>
<input type="email" {...getFieldProps("email")} />
{formFields.email.error && <span>{formFields.email.error}</span>}
</div>
<div>
<label>Password:</label>
<input type="password" {...getFieldProps("password")} />
{formFields.password.error && <span>{formFields.password.error}</span>}
</div>
<button type="submit">Sign Up</button>
</form>
);
};
export default SignupForm;
FAQs
A collection of helpful hooks for React
We found that magicui-hooks demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.