State Management in Front-end Web Development: Mutators
Libraries like Valtio and Pinia for Vue use a mutator pattern instead of the actions, dispatch, and...
找到 304 篇相关文章
Libraries like Valtio and Pinia for Vue use a mutator pattern instead of the actions, dispatch, and...
📈 Building the Future of Trading: An AI-Powered Platform for Smarter Investments The Introduction: Empowering Every Investor Hello, Builders and tech enthusiasts! I'm thrilled to share my journey as part of the "Meet The Builders" campaign, where innovators are leveraging Google AI to tackle real-world challenges. My project is an ambitious endeavor to democratize effective stock trading through an intuitive, AI-enabled platform. Inspired by industry leaders like Zerodha, I set out to create a comprehensive website that not only facilitates trading but also acts as a smart, AI-powered guide, helping users navigate the often-complex world of stock markets more effectively. This project is my story, a testament to how technology, especially AI, can empower individuals to make more informed investment decisions. The Deep Dive: Why Investors Need a Guiding Hand The stock market can be a daunting place. For many retail investors, it's a whirlwind of data, conflicting advice, and emotional decision-making that can lead to missed opportunities or significant losses. From understanding market trends and analyzing complex financial reports to knowing when to buy or sell, the sheer volume of information can be overwhelming. Many feel like they're trading blind, lacking the expertise and analytical tools available to professional institutions. I believe there's a significant gap here – a need for a personal, intelligent assistant that can cut through the noise, provide actionable insights, and guide users towards more strategic trading choices. This conviction fueled the inception of my project. The Solution: Stock Trading Platform – Intelligent Trading, Engineered for Success My project, Stock Trading Platform, is a robust web-based platform designed to simplify stock trading with the power of artificial intelligence. While currently in its final polishing stages on my local machine and version-controlled with Git and hosted on GitHub, the core functionality revolves around a
Your modal is open, centered, perfect. Then someone flicks the overlay and the page behind it scrolls away underneath. Everyone's first fix is the same three lines: useEffect (() => { document . body . style . overflow = open ? " hidden " : "" ; }, [ open ]); It works on your laptop. Then the bug reports arrive: On iPhone the page still moves. iOS Safari rubber-band scrolls the document by touch even with overflow: hidden on <body> . Something else got wiped. "" isn't necessarily what was there before — you just erased whatever your design system or CSS-in-JS had set inline. Two overlays, one frozen page. A drawer and a lightbox both own body.style.overflow ; close them in the wrong order and the page never scrolls again. The layout jumps the instant the desktop scrollbar disappears. useScrollLock from @reactuses/core is those three lines with the hard parts handled: it restores the exact inline overflow it replaced, adds a touchmove guard on iOS that still lets your modal's own content scroll, exposes the lock as React state you can render off, and works on any element — not just <body> . This post covers what it actually does line by line, why overflow: hidden is not enough on iOS, how it compares to the position: fixed and body:has(dialog[open]) approaches, and the six gotchas that show up in real apps. Quick Start npm install @reactuses/core import { useScrollLock } from " @reactuses/core " ; import { useEffect } from " react " ; function Modal ({ open , onClose , children }: ModalProps ) { // a getter, not `document.body` — see the SSR gotcha below const [, setLocked ] = useScrollLock (() => document . body ); useEffect (() => { setLocked ( open ); return () => setLocked ( false ); // release even if we unmount while open }, [ open , setLocked ]); if ( ! open ) return null ; return ( < div className = "overlay" onClick = { onClose } > < div className = "sheet" onClick = { e => e . stopPropagation () } > { children } </ div > </ div > ); } The signature: const [
React Router v8 was released on June 17, 2026, with minimal breaking changes and new baselines. Key updates include an ESM-only build and default middleware settings. React Router v6 and Remix v2 have reached End of Life. Developers should follow specific migration guidelines to update their applications, while some are considering alternatives like TanStack Router. By Daniel Curtis
I didn't want to write another "what's new in Next.js 16.3" post. Enough of those exist. I wanted to...
TypeScript 6.0 Strict Function Types: Why Contravariance Breaks Your Existing Callbacks This article was written with the assistance of AI, under human supervision and review. Most TypeScript migration failures stem from a single misunderstood compiler flag: strictFunctionTypes . The pattern that breaks production is deceptively simple—a callback that accepts a base type where the consumer expects a derived type. TypeScript 6.0 enables strict mode by default, which means codebases that never configured contravariance checking will fail to compile overnight. The failure mode here is subtle but expensive. A callback registered to an array method expects Animal , but the implementation passes Dog . Pre-6.0 TypeScript allowed this through bivariant parameter checking. Post-6.0, the compiler rejects it as unsafe. Teams scramble to fix hundreds of type errors without understanding the underlying variance rules, often choosing any or incorrect casts that introduce runtime bugs. The distinction between function properties and method signatures becomes critical—one enforces contravariance, the other permits bivariance for historical reasons. %% alt: Bivariant checking allows derived types where base types are expected The correct approach requires understanding contravariance: function parameters must accept types that are the same or less specific than what the function signature declares. When strictFunctionTypes activates, TypeScript enforces this rule for function properties but not method signatures. The solution is not to weaken types with any , but to restructure callbacks using proper variance-aware patterns or switch to method syntax where bivariance is intentional. %% alt: Contravariant checking enforces parameter safety at compile time This matters because the TypeScript 6.0 ecosystem assumes strict mode. Third-party libraries ship types built for contravariance. Disabling strictFunctionTypes to silence errors creates a type system that diverges from reality, wher
30 React.js Interview Questions You Should Know Before Your Next Frontend Interview ⚛️ Whether you're preparing for a frontend interview or simply want to brush up on your React.js knowledge , this guide covers 30 real-world, scenario-based React interview questions that interviewers frequently ask. The goal isn't just to memorize definitions. These questions are designed to help you understand how and when to apply React concepts in real-world applications . 📌 Bookmark this article and come back to it during your next interview preparation session. 📚 What We'll Cover In this guide, we'll explore questions around: Conditional rendering API calls and side effects Form validation Performance optimization State management Component re-rendering Keys and lists Dark mode Dynamic components useEffect vs useLayoutEffect Large-list optimization And much more... 1. How do you handle conditional rendering in React? Conditional rendering allows you to render different UI based on application state or conditions. You can use standard JavaScript techniques such as: if...else Ternary operators Logical && Example { isLoggedIn ? < Dashboard /> : < Login />} 💡 Interview Tip For simple conditions, a ternary operator or && is usually sufficient. For more complex conditions, consider moving the logic outside the JSX to keep the component readable. 2. You need to fetch API data when a component mounts. What's the best way to do it? 💡 Key Concept The typical approach is to perform the API request inside a useEffect hook when the component needs to fetch data after rendering. A common pattern is: useEffect (() => { // Fetch API data }, []); The empty dependency array indicates that the effect is intended to run after the initial render. Note: In modern React applications, the best approach can also depend on the framework or data-fetching library you're using. 3. How would you handle form validation in React? A common approach is to use controlled inputs and perform validation during even
The Quest Begins (The "Why") I still remember the first time I tried to add login to a side‑project. I’d read a tutorial that said “just store a token in localStorage and you’re good,” slapped together a few fetch calls, and called it a day. A week later I got an email from a user: “Hey, I can’t log out, and someone else seems to be using my account.” My heart sank. I realized I’d bolted a flashy lock onto a screen door — it looked secure, but anyone with a screwdriver could walk right in. That moment kicked off a deep dive. I wanted to understand the trade‑offs between sessions , JSON Web Tokens (JWT) , and OAuth so I could pick the right tool for each job, not just the shiniest one. What followed felt like assembling a superhero squad: each member has a unique power, and knowing when to call on them makes the difference between saving the day and causing collateral damage. The Revelation (The Insight) Sessions – The Trusty Sidekick Sessions are the classic, server‑side approach. When a user logs in, the server creates a random identifier (the session ID), stores it in a database or cache (Redis, Memcached, etc.), and sends it back to the browser as an HttpOnly cookie. On every request, the browser automatically includes that cookie, the server looks up the ID, and pulls the associated user data. Why I love it: The secret never leaves the server, so stealing a cookie only gives an attacker a session ID that’s useless without the server’s store. Revoking a session is trivial — just delete the row from the store. Works great for traditional web apps where you control both front‑ and back‑end. Where it stumbles: Horizontal scaling requires a shared session store; otherwise each instance forgets who the user is. Every request does a database/lookup, which can add latency if the store isn’t fast enough. JWT – The Lone Wolf with a Signed Badge A JWT is a compact, URL‑safe string that contains claims (like sub , exp , roles ) and is cryptographically signed (HMAC or RSA).
Shadcn, a design engineer at Vercel, has introduced new components for chat interfaces within the shadcn/ui project. This release includes components like MessageScroller and Message, focusing on conversation functionality. The approach emphasizes modular design, allowing developers to adapt elements without affecting underlying logic or styles. Support for headless components is also provided. By Daniel Curtis
A team-lead's breakdown of 8 real React Native project architectures — what each one actually solves, where the "Domain-Driven" and "Micro-Frontend" labels get misused, and how to pick one without over-engineering an MVP. The house-building analogy When you build a house, the labor that lays the bricks gets paid well. The architect who drew the blueprint gets paid more — because the architect already accounted for the second floor you'll add next year, and made sure the foundation could take the load without anyone tearing down a wall later. React Native codebases work the same way. The folder structure you pick on day one either lets your app absorb 10 more features and 40 more engineers, or it collapses under its own weight and someone gets hired specifically to rewrite it. This is also, almost word for word, what a React Native team lead interview is probing for: "Walk me through how you'd structure a project" or "What's your folder structure and why?" Nobody wants your code in that answer — they want to hear you reason about trade-offs. So here are eight real folder structures, what each one actually solves, and two places where the common naming gets sloppy. 1. Flat Structure — for prototypes and MVPs src/ ├── App.js ├── HomeScreen.js ├── ProfileScreen.js ├── Button.js ├── Card.js └── api.js Everything in one src/ folder, no categorization. When to use it: a client demo, a hackathon build, a single-screen proof of concept — anything with a short shelf life, or code you expect a bigger team to re-architect later. Where it breaks: past 10–15 files you're scrolling through an undifferentiated pile with no signal about what belongs together. 2. Feature-Based Structure — the industry default src/ └── features/ ├── auth/ │ ├── components/ │ ├── screens/ │ └── services/ ├── profile/ │ ├── components/ │ ├── screens/ │ └── services/ └── feed/ ├── components/ ├── screens/ └── services/ This is the most common structure in production RN apps. Each product area — auth, pro
App Review rejected my iOS app under Guideline 2.1. The note said reviewers were unable to locate the App Tracking Transparency permission request when they tested the build. The prompt worked on my iPhone. Every single launch. It just didn't work on theirs. The cause turned out to be two properties of the ATT API that are easy to miss individually and genuinely nasty in combination: together they produce a bug that is invisible on a fast device and completely reproducible on a slow one. Your test device is fast. The reviewer's device is not necessarily. This post is the root cause, the fix I shipped, and the list of other things that silently suppress the prompt. The two facts that explain everything 1. iOS only presents the ATT prompt while your app is active Apple's documentation for requestTrackingAuthorization(completionHandler:) states, for iOS 15 and later: "Calls to the API only prompt when the application state is UIApplicationStateActive." That's UIApplication.State.active — not merely "in the foreground," and not "the code is running." During launch there is a window where your JS/UI is already executing but the app is still inactive : splash screen dismissal, the first render, a modal transition animating in or out. Call the API in that window and iOS declines to present. 2. When iOS declines to present, you don't get an error You get notDetermined back ( undetermined in expo-tracking-transparency ) — which is the exact same value you get when the user simply hasn't answered yet. There is no "I couldn't show it" signal. There is no thrown error. There is no presented: false flag. From the return value alone, "the user hasn't decided yet" and "iOS silently no-op'd your request" are indistinguishable. That's the trap. The API looks like it succeeded. The bug I shipped Reduced to its essentials: // Called during startup, while the splash screen was still going away. const { status } = await requestTrackingPermissionsAsync (); const granted = status === ' gr
We just shipped EverShop 2.2.1 — the largest release since 2.0. It folds in the React 19 work that had been sitting in an unpublished 2.1.3 branch and stacks four months of development on top of it: a visual page builder, a blog module, entity custom fields, a multi-language storefront with a translated admin, a rebuilt shipping and fulfillment stack, built-in cloud storage, product recommendations, and a serious security and performance pass. If you're upgrading an existing store, one number to keep in mind: 31 database migrations across 10 modules run automatically on first start. Several of them transform data and drop legacy tables, so back up your database first and read the breaking-changes section below. This release also patches several security vulnerabilities, so upgrading promptly is the right move. Here's a tour of what's new, and what you'll need to change if you maintain themes or extensions. Visual Page Builder The headline feature is a drag-and-drop editor for the storefront, living at /admin/page-builder . You edit any storefront route — plus CMS pages and landing pages — by composing widgets into your theme's areas, with layout-aware drag/drop. The workflow is draft-based: changes accumulate in a per-admin, per-theme draft changeset with per-widget auto-save. When you're ready you can publish immediately, or schedule a rollout for later — and those rollout plans stay editable and cancelable right up until they run. There's inline editing on the canvas (text and images edited in place, with an image picker that understands cloud storage), a layers panel, a "Globals" view for site-wide areas, and per-widget styling controls. Link fields resolve products, categories, CMS pages, and blog posts through a single unified link resolver. Because it's touching public-facing content, the whole editor pipeline went through a dedicated security-hardening pass and ships with an end-to-end test suite. Blog module EverShop now has a first-class blog core module: p
One of the best ways to learn React is by building small, practical projects. A currency converter is an excellent example because it introduces state management, user input handling, calculations, and performance optimization—all in a single application. I built a simple currency converter using React that converts from USD to EUR, GBP, and JPY. For simplicity, I used fixed exchange rates instead of calling a live exchange rate API. React applications are interactive because they can respond to user actions. The useState hook allows components to remember values between renders. For this project, I declared it as thus, const [amount, setAmount] = useState(1); const [currency, setCurrency] = useState("EUR"); The amount stores the value entered. The setAmount() updates it. The currency variable stores the selected currency. The setCurrency() changes the selected currency. Whenever either value changes, React automatically re-renders the component. Now, to calculate the conversion, I stored the exchange rate in an object const RATES = { USD: 1, EUR: 0.92, GBP: 0.79, JPY: 157.3 }; The interface contains: A number input. A dropdown menu. A heading displaying the converted amount. Example: ```return ( Currency Converter <input type="number" value={amount} onChange={(e) => setAmount(Number(e.target.value))} /> <select value={currency} onChange={(e) => setCurrency(e.target.value)} > <option value="EUR">EUR</option> <option value="GBP">GBP</option> <option value="JPY">JPY</option> </select> <h2> {amount} USD = {convertedAmount} {currency} </h2> );```
Astro 7 focuses on build performance, utilizing native tooling and a rewritten compiler in Rust. The new version includes faster Markdown processing and stricter HTML rules. Recent updates introduced advanced routing and incremental builds, while issues around legacy file compatibility and dependency counts were raised in feedback. Astro targets content-driven sites with minimal JavaScript. By Daniel Curtis
Variable-size nodes break dagre's centering, first paint flickers, and straight chains render with kinked edges. Here is the why and the fix for each. Every React Flow and dagre tutorial shows the same thing: uniform gray boxes, laid out in a neat tree, everything centered. You copy the pattern, wire it up, and it works. Then you replace the gray boxes with real cards. A title that wraps to two lines. A card with a description and one without. And the layout starts to look subtly wrong: a parent sits off-center from its children, edges bend where they should be straight, and everything flashes in the top-left corner for a frame before jumping into place. I hit all three building an approval-workflow graph for a fintech app. The nodes were cards with variable content, so none of the fixed-size assumptions held. It took a while to understand that these are three separate bugs with three separate causes. So here is each one, why it happens, and the fix. At the end: the small package where I put all of it, so you do not have to rebuild this. Why dagre centers nodes off-balance (and the bounding-box fix) dagre centers a parent on the barycenter of its children, meaning the average of their center positions. That is correct when every child is the same size. It is visibly wrong when they are not. Concrete numbers from a graph I probed. A parent with two children, one 40px tall and one 200px tall. dagre puts the children at centers y=20 and y=180, so the parent lands at their average, y=100. But the visual middle of that group, the midpoint of the bounding box from the top of the small child to the bottom of the tall one, is y=140. The parent is 40px off from where your eye says it should be, and the taller the imbalance, the worse it gets. The fix is a post-pass on dagre's output: for every parent with two or more children, recompute its cross-axis position as the midpoint of the children's bounding box, walking deepest rank first so children settle before their parents.
TypeScript 6.0 --noPropertyAccessFromIndexSignature : The Flag That Forces Honest API Contracts This article was written with the assistance of AI, under human supervision and review. The Silent Type Hole in Your Codebase Most runtime property access errors stem from index signatures pretending to guarantee properties they don't. Teams define Record<string, T> or { [key: string]: T } for objects where specific properties might not exist, then access those properties with dot notation as if the type system proved their presence. The compiler stays silent. Production crashes follow when the property is undefined. The --noPropertyAccessFromIndexSignature flag eliminates this false confidence. When enabled, TypeScript prohibits dot notation for properties defined only through index signatures. The type system forces bracket notation instead, making the uncertainty explicit at every call site. This distinction is critical—it transforms implicit runtime failures into compile-time enforcement of honest contracts. When developers adopt this flag, the contract becomes explicit. Index signatures signal "this property might not exist" and the syntax enforces that uncertainty. Explicit properties signal "this property is guaranteed" and dot notation confirms the guarantee. The codebase gains honesty. Key Takeaways The --noPropertyAccessFromIndexSignature flag prevents dot notation on properties defined only through index signatures, forcing bracket notation that signals uncertainty. Index signatures ( [key: string]: T ) describe unknown property sets; explicit properties describe guaranteed contracts—the flag enforces this semantic difference. Enabling this flag exposes implicit runtime failures as compile errors, converting production crashes into immediate feedback during development. The migration path involves converting dot access to bracket notation for index-signature properties while keeping dot notation for explicit properties. Combining this flag with --noUncheckedInd
Part 1 was about waiting well. Part 2 was about not waiting at all. This one is about a value I...
If you're testing an iOS build with real devices, you've got two main paths: Apple's TestFlight, or Expo's EAS Preview using Ad-Hoc provisioning. They solve the same problem — getting a build onto a real iPhone without the App Store — but the workflows are genuinely different, not just cosmetically. How each one works TestFlight uses Apple's official infrastructure. You upload your build to App Store Connect (often via npx testflight to speed this up), Apple processes/reviews it, and testers install the TestFlight app and accept an email or public link invite. No UDID collection needed — Apple handles device registration behind the scenes. Expo EAS Preview (Ad-Hoc) uses Ad-Hoc provisioning. You register each tester's device UDID against your Apple Developer account before building — either manually (eas device:create, eas device:list) or by having the tester scan a QR code that installs a temporary profile. Once devices are tied to your provisioning profile, you build with: bash eas build --platform ios --profile preview This generates a direct install link/QR code — no App Store account or TestFlight app required. Comparison table Feature Expo Preview / Ad-Hoc Apple TestFlight Device limit ~100 devices/device class/year (Apple Developer account tier) Up to 10,000 external testers Processing time Immediate after cloud build finishes Apple review/processing (mins to hours) UDID management Manual or profile-based registration required Not required, handled by Apple Best for Fast internal testing, client demos, strict ad-hoc distribution Larger-scale beta testing, staging before production Which one should you use? Fast internal iteration, client demos, small teams → Ad-Hoc. No waiting on Apple, instant install links. Wider beta testing before a production release → TestFlight. Built-in scale, no manual device management. Most teams I've worked with end up using both at different stages: Ad-Hoc during active development for quick feedback loops, TestFlight once the bui
The easiest way to remember it: preventDefault() → stops the browser's default action. stopPropagation() → stops the event from moving through the DOM. event.preventDefault() It prevents the browser's built-in behavior associated with an event. Example: clicking a link. Google document.getElementById("link").addEventListener("click", (event) => { event.preventDefault(); }); Normally: Click ↓ Browser navigates to Google With preventDefault(): Click ↓ preventDefault() ↓ ❌ Browser does NOT navigate Common uses: // Form submission event.preventDefault(); // Link navigation event.preventDefault(); // Drag/drop browser behavior event.preventDefault(); event.stopPropagation() This prevents the event from bubbling up or capturing down through parent/child elements. Example: Click me parent.addEventListener("click", () => { console.log("Parent clicked"); }); child.addEventListener("click", (event) => { event.stopPropagation(); console.log("Button clicked"); }); Without stopPropagation(): Click Button ↓ Button handler ↓ Parent handler Output: Button clicked Parent clicked With stopPropagation(): Click Button ↓ Button handler ↓ stopPropagation() ↓ ❌ Parent handler doesn't receive the event The important difference Imagine: Like If you click the button: preventDefault() button.addEventListener("click", (event) => { event.preventDefault(); }); The event can still propagate: Button ↓ Anchor ↓ Card But the browser's default action (such as following the link) is prevented. stopPropagation() button.addEventListener("click", (event) => { event.stopPropagation(); }); The event doesn't continue through the DOM: Button ↓ ❌ Anchor/Card handlers But the browser's default behavior is not automatically cancelled. Can you use both? Yes. button.addEventListener("click", (event) => { event.preventDefault(); event.stopPropagation(); }); Now you're saying: Don't perform the browser's default action. Don't let this event reach other elements.
This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry. Introduction: The...