Web Development Documentation
website·Indexed 29 days ago
https://web-docs.youtingkun.com/A comprehensive guide to front-end development covering JavaScript (variables, destructuring, debounce/throttle), CSS (Flexbox, Grid, animations, selectors), HTML (elements, lazy loading), React Hooks (useState, useEffect, useMemo, useCallback, useContext, useReducer, useRef, useLayoutEffect, useImperativeHandle, useDebugValue), and Linux basics including the ls command.
What's inside Web Docs
- JavaScript is an interpreted language used for developing both web pages and network applications.
Understand JavaScript Destructuring Assignment basics
Destructuring assignment is a syntax that allows unpacking values from arrays, objects, or strings into distinct variables. A critical constraint is that destructuring performs a shallow copy of the first level only; it does not perform a deep copy.Understand the purpose and motivation of React Hooks
Introduced in React 16.8, Hooks allow developers to use state, props, context, and refs within functional components without writing class components. The primary motivations for Hooks are:
- State Reuse: Hooks make it easier to reuse stateful logic between components compared to class components.
- Logic Separation: Hooks allow complex logic within lifecycle methods to be extracted into smaller, reusable functions, reducing the complexity of components.
Manage component state using the useState hook
The
useStatehook allows you to declare state variables in React functional components. It accepts an initial state value as its argument and returns an array containing two elements: the current state value (index 0) and a setter function to update that state (index 1).Crucially, hooks must be called at the top level of the function; they cannot be placed inside conditional statements (like
iforelse) or loops to ensure that the order of hook execution remains consistent across renders.import React, { useState } from "react"; function Example() { // Declare a state variable named "count" initialized to 0 const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> {/* Use setCount to update the state, similar to setState() in class components */} <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }Perform shallow and deep cloning of objects and arrays
Shallow copying copies the reference pointer, meaning the new and old objects share the same memory. Deep cloning creates a completely independent copy of the data structure.
Object Deep Cloning:
- Use
JSON.parse(JSON.stringify(obj)), though this may fail for certain data types.
Array Cloning (First level):
- Use
.slice(0),.map(), or.concat().
// Object Deep Clone (Simple) const clone = JSON.parse(JSON.stringify(originalObject)); // Array Shallow Clone var arr1 = [1, 2, 3]; var arr2 = arr1.slice(0); var arr3 = arr1.map(v => v); var arr4 = arr1.concat();- Use
Pass data to deeply nested components using useContext
TheuseContexthook allows a component to access data from a context object (created viaReact.createContext) without passing props through every intermediate level of the component tree. It returns the current value of the context, which is determined by thevalueprop of the nearest<MyContext.Provider>above the component in the tree.import React, { useContext } from 'react'; const themes = { light: { foreground: "#000000", background: "#eeeeee", }, dark: { foreground: "#ffffff", background: "#222222", }, }; // 1. Create the context with a default value const ThemeContext = React.createContext(themes.light); function App() { // 2. Provide the context value to the component tree return ( <ThemeContext.Provider value={themes.dark}> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar(props) { // Toolbar does not need to pass the theme prop to ThemedButton return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { // 3. Consume the context value using the useContext hook const theme = useContext(ThemeContext); return ( <button style={{ background: theme.background, color: theme.foreground }}> I am styled by theme context! </button> ); }Manage complex state with useReducer
TheuseReducerhook is preferable touseStatewhen state logic is complex, contains multiple sub-values, or when the next state depends on the previous state. Additionally,useReducercan optimize performance for components triggering deep updates because you can pass thedispatchfunction to child components instead of creating new callback functions on every render.const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({ type: "decrement" })}>-</button> <button onClick={() => dispatch({ type: "increment" })}>+</button> </> ); }Prevent unnecessary child re-renders with React.memo
By default, a React child component re-renders whenever its parent component renders, regardless of whether the child's props have changed. Wrapping a functional component inmemoensures that the child component only re-renders if its own props change, optimizing performance when the parent's state changes do not affect the child.import React, { memo } from "react"; // The Child component will only re-render if props.value changes const Child = memo(function Child(props) { console.log("Child render"); return <h1>value: {props.value}</h1>; });Follow the rules of using React Hooks
To ensure hooks work correctly, you must adhere to these two critical rules:
- Call hooks at the top level: Only call hooks at the top level of your function. Do not call hooks inside loops, conditions, or nested functions.
- Call hooks only in React functions: Hooks must be called within React functional components or custom hooks. Calling them in regular JavaScript functions is invalid.
Destructure arrays in JavaScript
Array destructuring assigns values based on their index position. It supports skipping elements using commas, capturing remaining elements using the rest operator (...), and providing default values. Note that default values are only applied if the source value isundefined;nullwill not trigger the default value.// Basic usage and nesting let [a, [b, c]] = [1, [2, 3]]; // a=1, b=2, c=3 // Skipping elements let [, , c1] = [1, 2, 3]; // c1=3 // Rest operator let [a2, ...c2] = [1, 2, 3]; // a2=1, c2=[2, 3] // Default values let [a1 = 1, b1, c1] = [, 3, 4]; // a1=1, b1=3, c1=4 let [a2 = 1] = [undefined]; // a2=1 let [a3 = 1] = [null]; // a3=nullDetermine data types in JavaScript
There are several ways to check the type of a value:
typeof: Works for most primitives but returns'object'fornull, arrays, and dates. It correctly identifies functions as'function'.Object.prototype.toString.call(): The most accurate and commonly used method for precise type detection.- Specific helpers: Such as
Array.isArray().
typeof Symbol(); // 'symbol' typeof ''; // 'string' typeof 1; // 'number' typeof true; // 'boolean' typeof undefined; // 'undefined' typeof BigInt(1); // 'bigint' typeof null; // 'object' (Incorrect) typeof []; // 'object' typeof {}; // 'object' typeof console.log; // 'function'Use useRef to access DOM elements imperatively
TheuseRefhook returns a mutable ref object whose.currentproperty is initialized to the passed argument (initialValue). The returned ref object persists for the entire lifetime of the component. A common use case is to access a child component or DOM element imperatively, such as focusing a text input.import { useRef } from 'react'; function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` points to the text input element mounted on the DOM inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>Focus the input</button> </> ); }