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.

Tokens
9.9K
Snippets
50
Records
73
Agent score
49%

What's inside Web Docs

  1. 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.
  2. 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:

    1. State Reuse: Hooks make it easier to reuse stateful logic between components compared to class components.
    2. Logic Separation: Hooks allow complex logic within lifecycle methods to be extracted into smaller, reusable functions, reducing the complexity of components.
  3. Manage component state using the useState hook

    The useState hook 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 if or else) 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>
      );
    }
  4. 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();
  5. Pass data to deeply nested components using useContext

    The useContext hook allows a component to access data from a context object (created via React.createContext) without passing props through every intermediate level of the component tree. It returns the current value of the context, which is determined by the value prop 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>
      );
    }
  6. Manage complex state with useReducer

    The useReducer hook is preferable to useState when state logic is complex, contains multiple sub-values, or when the next state depends on the previous state. Additionally, useReducer can optimize performance for components triggering deep updates because you can pass the dispatch function 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>
        </>
      );
    }
  7. 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 in memo ensures 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>;
    });
  8. Follow the rules of using React Hooks

    To ensure hooks work correctly, you must adhere to these two critical rules:

    1. 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.
    2. 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.
  9. 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 is undefined; null will 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=null
  10. Determine data types in JavaScript

    There are several ways to check the type of a value:

    1. typeof: Works for most primitives but returns 'object' for null, arrays, and dates. It correctly identifies functions as 'function'.
    2. Object.prototype.toString.call(): The most accurate and commonly used method for precise type detection.
    3. 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'
  11. Use useRef to access DOM elements imperatively

    The useRef hook returns a mutable ref object whose .current property 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>
        </>
      );
    }