当前位置: 首页 > article >正文

React基础知识(总结回顾一)

React知识框架图可以帮助理清React的核心概念及其相关技术。下面是一个大致的React知识框架图,按功能模块将React的核心知识进行分类,包括从基础到进阶的内容。

React 知识框架图:

+---------------------+
|     React 基础      |
+---------------------+
        |
        |--- JSX语法
        |--- 函数组件与类组件
        |--- 渲染机制(虚拟DOM、渲染流程)
        |--- 事件处理(onClick, onChange)
        |--- 条件渲染与列表渲染
        |--- 受控组件与非受控组件
        |--- 基本的组件通信(props, state)
        |
+---------------------+
|     React Hooks     |
+---------------------+
        |
        |--- useState
        |--- useEffect
        |--- useContext
        |--- useRef
        |--- useReducer
        |--- useCallback
        |--- useMemo
        |
+---------------------+
|     React 路由      |
+---------------------+
        |
        |--- React Router (v6)
        |--- 路由配置(Route, Switch, Link)
        |--- 嵌套路由与动态路由
        |--- 重定向与路由守卫
        |
+---------------------+
|    组件间通信       |
+---------------------+
        |
        |--- 父子组件通信(props)
        |--- 子父组件通信(通过回调函数传递数据)
        |--- Context API(跨层级共享状态)
        |--- 自定义Hooks(共享逻辑)
        |
+---------------------+
|     状态管理       |
+---------------------+
        |
        |--- useState / useReducer(局部状态)
        |--- Redux(全局状态管理)
        |--- Redux Toolkit
        |--- MobX
        |
+---------------------+
|   性能优化与调试    |
+---------------------+
        |
        |--- React.memo
        |--- useMemo
        |--- useCallback
        |--- shouldComponentUpdate
        |--- React Profiler
        |--- 懒加载与代码分割(React.lazy & Suspense)
        |
+---------------------+
|     高级功能       |
+---------------------+
        |
        |--- 动态导入(React.lazy)
        |--- Suspense与错误边界
        |--- React Portals
        |--- HOC(高阶组件)
        |--- Render Props
        |--- 自定义Hooks
        |--- Context API优化
        |
+---------------------+
|     测试与部署     |
+---------------------+
        |
        |--- 单元测试(Jest, React Testing Library)
        |--- 快照测试(Snapshot Testing)
        |--- 端到端测试(Cypress)
        |--- Webpack与Babel配置
        |--- CI/CD与自动化部署
        |
+---------------------+
|   配置与工具链     |
+---------------------+
        |
        |--- Webpack
        |--- Babel
        |--- ESLint / Prettier
        |--- Create React App (CRA)
        |--- Next.js / Gatsby
        |

解释:

  1. React基础

    • JSX语法:React的组件通常使用JSX(JavaScript XML),它允许你在JavaScript中写HTML。
    • 函数组件与类组件:函数组件更为简洁,类组件在React中较为传统,但不再推荐使用。
    • 渲染机制:React使用虚拟DOM优化UI渲染的效率,更新时对比虚拟DOM与真实DOM,尽量减少DOM操作。
    • 受控组件与非受控组件:受控组件的值由React状态控制,非受控组件的值由DOM本身管理。
    • 事件处理:React使用事件委托机制处理事件,减少内存使用并提高性能。
  2. React Hooks

    • useState:用于管理组件内部的状态。
    • useEffect:用于处理副作用(例如数据请求、DOM操作等)。
    • useContext:用于跨越组件层级传递数据。
    • useRef:引用DOM元素或保存可变的状态。
    • useReducer:用于更复杂的状态管理。
    • useCallbackuseMemo:优化性能,避免不必要的渲染和计算。
  3. React 路由

    • 使用 React Router 管理页面路由,支持动态路由、嵌套路由、重定向等。
    • 通过 Link 组件实现页面跳转。
  4. 组件间通信

    • Props:父组件通过props传递数据给子组件。
    • 回调函数:子组件通过回调函数将数据传递回父组件。
    • Context API:在多个组件间共享全局状态,避免层层传递props
  5. 状态管理

    • 使用 useStateuseReducer 管理局部组件状态。
    • Redux:用于全局状态管理,适合大型应用。
    • Redux Toolkit:简化Redux的使用,减少样板代码。
  6. 性能优化与调试

    • React.memo:避免函数组件的重复渲染。
    • useMemo & useCallback:优化性能,避免不必要的计算和函数创建。
    • React Profiler:帮助分析组件渲染性能。
    • 懒加载与代码分割:通过 React.lazySuspense 实现组件的懒加载,减少初次加载时的资源大小。
  7. 高级功能

    • React Portals:让子组件能够渲染到父组件之外的DOM节点中,常用于模态框、弹出层等场景。
    • 高阶组件(HOC):一种用于复用组件逻辑的模式。
    • Render Props:通过函数作为props传递数据,实现组件之间的共享逻辑。
    • 自定义Hooks:封装复用逻辑,使代码更加模块化。
  8. 测试与部署

    • 单元测试:通过Jest和React Testing Library对组件进行单元测试。
    • 快照测试:通过快照对比组件渲染结果,确保UI不会出现意外变动。
    • 端到端测试:使用Cypress等工具进行端到端的UI测试。
    • CI/CD:集成持续集成与持续部署,自动化构建和部署过程。
  9. 配置与工具链

    • Webpack:打包工具,帮助将多个文件打包成一个文件,提升加载性能。
    • Babel:JavaScript转译工具,将ES6+代码转换为兼容浏览器的代码。
    • ESLint & Prettier:静态代码分析和格式化工具,帮助保持代码质量。
    • Next.js & Gatsby:基于React的框架,分别用于服务器端渲染(SSR)和静态网站生成。

总结:

这个框架图按模块从基础到进阶覆盖了React的各个方面。每个模块包含了React开发中最常用的工具、技术和概念。如果你在学习React,可以逐步深入每个领域并理解其细节,掌握这些知识将有助于你应对React相关的面试和项目开发。
下面详细解释React的基础和进阶知识点,并给出相关代码示例。

React基础

1. JSX语法

JSX(JavaScript XML)是React的核心语法扩展,允许我们在JavaScript中写类似HTML的代码。它被最终转换为React.createElement()方法调用,生成虚拟DOM元素。

示例:

import React from 'react';

function Welcome() {
  return <h1>Hello, world!</h1>;  // JSX语法,返回一个h1元素
}

export default Welcome;

解释:

  • JSX语法看起来像HTML,但它实际是在背后转化成了React.createElement()调用,因此我们可以在其中使用JavaScript表达式,如:

    const name = 'Alice';
    return <h1>Hello, {name}!</h1>;
    
2. 函数组件与类组件
  • 函数组件:更简洁,推荐用于大部分React开发,尤其是配合Hooks。
  • 类组件:传统的React组件形式,通常用于需要状态或生命周期钩子的场景,但已被函数组件和Hooks取代。

函数组件示例:

import React from 'react';

function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

export default Greeting;

类组件示例:

import React, { Component } from 'react';

class Greeting extends Component {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

export default Greeting;

解释:

  • 函数组件更加简洁且易于维护。
  • 类组件提供了更多生命周期方法和状态管理的能力。
3. 渲染机制

React通过虚拟DOM提高性能。每次状态或props发生变化时,React会生成一个虚拟DOM并与旧的虚拟DOM进行比较(称为“diffing”算法),然后仅将差异部分更新到真实DOM中,从而最小化DOM操作,提高性能。

示例:

const [count, setCount] = useState(0);

// 虚拟DOM会在每次状态更新时进行对比,只更新不同的部分
return <button onClick={() => setCount(count + 1)}>{count}</button>;
4. 受控组件与非受控组件
  • 受控组件:组件的值由React的状态管理,每当输入发生变化时,React状态会更新。
  • 非受控组件:表单元素的值由DOM管理,React不直接干预。

受控组件示例:

import React, { useState } from 'react';

function ControlledInput() {
  const [value, setValue] = useState('');

  const handleChange = (e) => setValue(e.target.value);

  return <input type="text" value={value} onChange={handleChange} />;
}

export default ControlledInput;

非受控组件示例:

import React, { useRef } from 'react';

function UncontrolledInput() {
  const inputRef = useRef();

  const handleSubmit = () => {
    alert(inputRef.current.value);  // 通过ref获取值
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );
}

export default UncontrolledInput;
5. 事件处理

React使用事件委托机制处理事件,事件处理函数通过props传递给子组件,并且自动绑定到DOM元素。

示例:

function Button() {
  const handleClick = () => {
    alert('Button clicked!');
  };

  return <button onClick={handleClick}>Click Me</button>;
}

export default Button;

React Hooks

1. useState

useState是一个用于管理组件内部状态的Hook。

示例:

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);  // 初始化count为0

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default Counter;
2. useEffect

useEffect用于处理副作用,比如数据获取、订阅等,类似于类组件中的componentDidMountcomponentDidUpdate

示例:

import React, { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);

    return () => clearInterval(interval);  // 清理副作用
  }, []);  // 只有在组件挂载时执行

  return <p>Timer: {seconds} seconds</p>;
}

export default Timer;
3. useContext

useContext用于访问Context中的数据,避免通过层层props传递数据。

示例:

const ThemeContext = React.createContext('light');

function ThemedComponent() {
  const theme = useContext(ThemeContext);  // 使用useContext获取值
  return <p>Current theme is {theme}</p>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedComponent />
    </ThemeContext.Provider>
  );
}

export default App;
4. useRef

useRef用于引用DOM元素或存储可变数据(如计时器ID),并且不会触发重新渲染。

示例:

import React, { useRef } from 'react';

function FocusInput() {
  const inputRef = useRef();

  const handleFocus = () => {
    inputRef.current.focus();  // 让input获取焦点
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={handleFocus}>Focus the input</button>
    </div>
  );
}

export default FocusInput;
5. useReducer

useReducer用于处理复杂的状态管理,类似于Redux的Reducer。

示例:

import React, { useReducer } from 'react';

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:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
    </div>
  );
}

export default Counter;
6. useCallbackuseMemo

这两个Hooks用于性能优化:

  • useCallback:缓存函数,避免每次渲染都创建新的函数。
  • useMemo:缓存计算结果,避免每次渲染都进行昂贵的计算。

示例:

import React, { useState, useCallback, useMemo } from 'react';

function ExpensiveComponent({ count }) {
  const calculateFactorial = useMemo(() => {
    return factorial(count);
  }, [count]);

  const increment = useCallback(() => {
    alert('Button clicked');
  }, []);  // 只有依赖项变化时才重新创建函数

  return (
    <div>
      <p>Factorial: {calculateFactorial}</p>
      <button onClick={increment}>Click</button>
    </div>
  );
}

function factorial(num) {
  if (num === 0) return 1;
  return num * factorial(num - 1);
}

React 路由

1. React Router

React Router用于在React应用中实现路由功能。

示例:

import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';

function Home() {
  return <h2>Home Page</h2>;
}

function About() {
  return <h2>About Page</h2>;
}

function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>
      <Switch>
        <Route path="/" exact component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

export default App;

解释:

  • BrowserRouter:包裹整个应用

,管理路由。

  • Route:定义页面路由和匹配路径。
  • Switch:确保只渲染一个Route

组件间通信

1. Props

父组件通过props传递数据给子组件。

示例:

function Parent() {
  const message = 'Hello from Parent!';
  return <Child message={message} />;
}

function Child({ message }) {
  return <p>{message}</p>;
}
2. 回调函数

子组件通过回调函数传递数据给父组件。

示例:

function Parent() {
  const [data, setData] = useState('');

  const handleData = (childData) => {
    setData(childData);
  };

  return (
    <div>
      <Child onData={handleData} />
      <p>Data from child: {data}</p>
    </div>
  );
}

function Child({ onData }) {
  return <button onClick={() => onData('Data from Child')}>Send Data</button>;
}
3. Context API

用于跨层级组件共享状态。

示例:

const ThemeContext = React.createContext('light');

function Child() {
  const theme = useContext(ThemeContext);
  return <p>Current theme: {theme}</p>;
}

function Parent() {
  return (
    <ThemeContext.Provider value="dark">
      <Child />
    </ThemeContext.Provider>
  );
}

状态管理

1. useState 和 useReducer

如前面所述,useState用于简单的局部状态管理,useReducer用于复杂的状态管理。

2. Redux

Redux是全局状态管理工具,适合大型应用。

示例:

import { createStore } from 'redux';

const initialState = { count: 0 };

function reducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    default:
      return state;
  }
}

const store = createStore(reducer);

store.dispatch({ type: 'INCREMENT' });
console.log(store.getState());  // { count: 1 }
3. Redux Toolkit

简化了Redux的使用,减少了样板代码。

示例:

import { createSlice, configureStore } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { count: 0 },
  reducers: {
    increment: (state) => {
      state.count += 1;
    },
  },
});

const store = configureStore({
  reducer: counterSlice.reducer,
});

store.dispatch(counterSlice.actions.increment());
console.log(store.getState());  // { count: 1 }

以上是React中的一些基础和进阶知识点的详细解释与代码示例。掌握这些内容将帮助你在开发React应用时更加高效,并在面试中展示你扎实的React基础。
————————————————————————————————

在React的前端面试中,以下是常见的面试点,每个点都涉及React的核心概念、使用方法和代码示例。理解并熟练应用这些概念,将有助于你在React面试中表现出色。

1. 组件的生命周期(componentDidMount, useEffect等)

React的生命周期方法在类组件中用来处理组件的挂载、更新和卸载等操作。函数组件通过useEffect Hook来模拟生命周期方法。

类组件生命周期方法
  • componentDidMount:组件挂载后执行。
  • componentDidUpdate:组件更新时执行。
  • componentWillUnmount:组件卸载时执行。
class MyComponent extends React.Component {
  componentDidMount() {
    console.log('Component mounted');
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('Component updated');
  }

  componentWillUnmount() {
    console.log('Component will unmount');
  }

  render() {
    return <div>Component Lifecycle</div>;
  }
}
函数组件中使用useEffect

useEffect Hook在函数组件中用于处理副作用,比如数据加载、定时器、订阅等。它代替了类组件中的componentDidMountcomponentDidUpdatecomponentWillUnmount等生命周期方法。

import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    console.log('Component mounted');

    // Cleanup function
    return () => {
      console.log('Component will unmount');
    };
  }, []); // 空数组表示仅在挂载和卸载时执行

  return <div>Component Lifecycle</div>;
}

2. Hooks的使用与原理

React的Hooks API允许在函数组件中使用状态和副作用等特性,而无需写类组件。常用的Hooks有useStateuseEffectuseContextuseReducer等。

useState

useState用于管理函数组件的局部状态。

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);  // 初始状态为0

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
useEffect

useEffect用于处理副作用(如数据请求、DOM操作等)。它可以模拟componentDidMountcomponentDidUpdatecomponentWillUnmount

import { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);

    return () => clearInterval(interval);  // 清理副作用
  }, []);  // 空数组表示仅在挂载和卸载时执行

  return <p>Timer: {seconds} seconds</p>;
}
useContext

useContext用于跨层级组件共享数据,而不必通过props逐层传递。

import { useContext } from 'react';

const MyContext = React.createContext();

function Child() {
  const value = useContext(MyContext);  // 获取Context值
  return <p>{value}</p>;
}

function Parent() {
  return (
    <MyContext.Provider value="Hello from context">
      <Child />
    </MyContext.Provider>
  );
}
useReducer

useReducer用于管理更复杂的状态逻辑,类似于useState,但适用于更复杂的状态管理。

import { useReducer } from 'react';

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:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
    </div>
  );
}

3. 组件通信(props传递数据、useContext跨组件通信)

React组件可以通过props进行父子组件的数据传递,也可以使用useContext跨组件共享状态。

通过props传递数据

父组件通过props将数据传递给子组件。

function Parent() {
  const message = 'Hello from Parent';
  return <Child message={message} />;
}

function Child({ message }) {
  return <p>{message}</p>;
}
通过useContext进行跨组件通信

useContext让我们可以通过Context在整个应用中共享数据,避免逐层传递props

const ThemeContext = React.createContext('light');

function Child() {
  const theme = useContext(ThemeContext);  // 获取当前主题
  return <p>Current Theme: {theme}</p>;
}

function Parent() {
  return (
    <ThemeContext.Provider value="dark">
      <Child />
    </ThemeContext.Provider>
  );
}

4. 虚拟DOM的工作原理

React通过虚拟DOM提高性能。每次组件状态更新时,React会生成一个虚拟DOM(内存中的对象),然后与之前的虚拟DOM进行比较(即"diffing"算法)。最后,React会计算出最小的DOM操作来更新实际的DOM。

  • 虚拟DOM:React将UI渲染为虚拟DOM树,避免直接操作真实DOM,从而提高性能。

5. 事件处理(onClick, onChange等)

React的事件处理是通过事件代理机制实现的。事件的绑定与浏览器原生事件不同,React会将事件处理函数直接传递给虚拟DOM。

function MyButton() {
  const handleClick = () => {
    alert('Button clicked!');
  };

  return <button onClick={handleClick}>Click Me</button>;
}

6. 条件渲染与列表渲染(map, &&运算符)

条件渲染

通过条件语句来决定是否渲染某些内容。

function MyComponent({ isLoggedIn }) {
  return isLoggedIn ? <p>Welcome back!</p> : <p>Please log in.</p>;
}
列表渲染

通过map方法渲染列表。

function List({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

7. 受控组件与非受控组件的区别

  • 受控组件:组件的状态由React的状态管理。
  • 非受控组件:表单元素的值由DOM自己管理,React不直接干预。
受控组件
function Form() {
  const [value, setValue] = useState('');

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  return <input value={value} onChange={handleChange} />;
}
非受控组件
function Form() {
  const inputRef = useRef();

  const handleSubmit = () => {
    alert(inputRef.current.value);
  };

  return <input ref={inputRef} />;
}

8. React性能优化(React.memo, useMemo, useCallback

React.memo

React.memo是一个高阶组件,用于避免函数组件的重复渲染。

const Child = React.memo(function Child({ count }) {
  console.log('Child rendered');
  return <p>Count: {count}</p>;
});
useMemo

useMemo用于缓存计算结果,避免不必要的计算。

function ExpensiveComponent({ number }) {
  const computedValue = useMemo(() => expensiveCalculation(number), [number]);
  return <p>{computedValue}</p>;
}
useCallback

useCallback用于缓存函数实例,避免每次渲染都创建新的函数。

const handleClick = useCallback(() => {
  console.log('Button clicked');
}, []); // 只有依赖项变化时才会重新创建函数

9. React Router 和 Redux

React Router

React Router用于管理React应用的路由。

import

 { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/about" component={AboutPage} />
        <Route path="/" component={HomePage} />
      </Switch>
    </Router>
  );
}
Redux

Redux是一个用于全局状态管理的库,它使用一个集中式的store来存储状态,并通过dispatch触发状态更新。

import { createStore } from 'redux';

const initialState = { count: 0 };

function reducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    default:
      return state;
  }
}

const store = createStore(reducer);

store.dispatch({ type: 'INCREMENT' });
console.log(store.getState());  // { count: 1 }

总结

这些是React面试中常见的面试点和相关概念,包括生命周期、Hooks、组件通信、虚拟DOM、事件处理、条件渲染、性能优化等。掌握这些核心知识,不仅可以帮助你更好地理解React的工作原理,还能在面试中展示你的React开发技能。


http://www.kler.cn/a/450967.html

相关文章:

  • StarRocks一次复杂查询引起的Planner超时异常
  • Issac ROS navigation测试
  • 深入解读数据资产化实践指南(2024年)
  • DevNow x Notion
  • 一个比RTK或redux更轻量级更易使用的 React 第三方状态管理工具库的配置与使用
  • 信号仿真高级工程师面试题
  • WebSSH:基于Go实现的高效Web SSH客户端指南
  • ReentrantLock底层原理、源码解析
  • 共享无人系统,从出行到生活全面覆盖
  • python环境中阻止相关库的自动更新
  • 迁移学习 详解及应用示例
  • 36 Opencv SURF 关键点检测
  • Nexa AI发布OmniAudio-2.6B:一款快速的音频语言模型,专为边缘部署设计
  • 【记录——解除网课自动暂停】的“魔法“
  • IntelliJ IDEA中设置激活的profile
  • Centos下的OpenSSH服务器和客户端
  • 【算法篇】——数据结构中常见八大排序算法的过程原理详解
  • 深入解析 Apache APISIX
  • 14-zookeeper环境搭建
  • 解决前端笔记本电脑屏幕显示缩放比例125%、150%对页面大小的影响问题--数据可视化大屏
  • C语言项目 天天酷跑(上篇)
  • day53 第十一章:图论part04
  • Ruby Raider使用教程
  • 基于小程序宿舍报修系统的设计与实现ssm+论文源码调试讲解
  • C++ —— 模板类具体化
  • 图像处理-Ch2-空间域的图像增强