Skip to content

7.6 已OFFER

1. 组件封装思路

封装组件的主要目标是提高代码复用性、易维护性和可测试性。以下是一些封装组件的思路:

  • 高内聚,低耦合:组件的内部实现应当与外部使用尽量解耦,减少组件的依赖性,使组件更易于重用和维护。

  • 单一职责:每个组件应该只负责一项任务,如展示一个 UI 元素、处理特定的逻辑等。避免组件职责过于复杂。

  • 可配置性:通过 props 传递参数,使组件具备一定的灵活性和可配置性。组件内部应支持合理的默认值和必要的验证。

  • 状态管理:根据需要合理管理组件的内部状态,确定哪些状态需要提升至父组件或使用全局状态管理工具(如 Redux)。

  • 使用 Hooks:React Hooks(如 useStateuseEffect 等)可以帮助简化逻辑,避免复杂的生命周期管理。

  • 分离样式和逻辑:通过 CSS-in-JS 或 styled-components,将样式与逻辑分离,使代码更加清晰。

  • 组合模式:使用组合模式代替继承,通过组合多个简单组件来构建复杂组件。

2. 父子组件交互实例

父子组件之间的交互可以通过 props 和回调函数实现。

父组件

javascript
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';

function ParentComponent() {
  const [message, setMessage] = useState('Hello from Parent');

  const handleMessageChange = (newMessage) => {
    setMessage(newMessage);
  };

  return (
    <div>
      <h1>Parent Component</h1>
      <ChildComponent message={message} onMessageChange={handleMessageChange} />
    </div>
  );
}

export default ParentComponent;

子组件

javascript
import React from 'react';

function ChildComponent({ message, onMessageChange }) {
  const updateMessage = () => {
    onMessageChange('Hello from Child');
  };

  return (
    <div>
      <h2>Child Component</h2>
      <p>{message}</p>
      <button onClick={updateMessage}>Update Message</button>
    </div>
  );
}

export default ChildComponent;

在这个例子中,ParentComponent 通过 props 将状态 message 和修改状态的函数 onMessageChange 传递给 ChildComponent。子组件通过调用 onMessageChange 修改父组件的状态。

3. 数组解构

数组解构允许从数组中提取值,并将其赋值给变量。

示例

javascript
const [a, b, c] = [1, 2, 3];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

// 也可以跳过一些元素
const [first, , third] = [10, 20, 30];
console.log(first); // 10
console.log(third); // 30

4. 父组件调用子组件方法

为了让父组件调用子组件中的方法,可以使用 React.forwardRefuseImperativeHandle

示例

子组件

javascript
import React, { forwardRef, useImperativeHandle } from 'react';

const ChildComponent = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    childMethod() {
      console.log('Child method called');
    }
  }));

  return <div>Child Component</div>;
});

export default ChildComponent;

父组件

javascript
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';

function ParentComponent() {
  const childRef = useRef();

  const callChildMethod = () => {
    if (childRef.current) {
      childRef.current.childMethod();
    }
  };

  return (
    <div>
      <h1>Parent Component</h1>
      <ChildComponent ref={childRef} />
      <button onClick={callChildMethod}>Call Child Method</button>
    </div>
  );
}

export default ParentComponent;

5. React Hooks 示例

  • useState:管理组件内部的状态。
javascript
const [count, setCount] = useState(0);
  • useEffect:管理副作用,如数据获取、订阅、DOM 操作等。
javascript
useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]);
  • useRef:引用 DOM 元素或保持跨渲染周期的值。
javascript
const inputRef = useRef(null);
  • useContext:共享组件树中的数据。
javascript
const value = useContext(MyContext);

6. useState 和 useRef 的区别

  • useState:用于声明组件的状态变量,更新状态会触发组件重新渲染。

  • useRef:用于创建一个保持跨渲染周期的可变引用,改变 useRef 的值不会触发组件重新渲染。

7. 改变数组或对象以触发重新渲染

useState 中存储的是数组或对象时,不能直接修改原始数据结构,否则不会触发重新渲染。需要创建新数组或对象来进行更新。

javascript
// 错误方式:直接修改不会触发渲染
const [state, setState] = useState({ name: 'John', age: 30 });
state.name = 'Jane';
setState(state); // 不会触发渲染

// 正确方式:创建新对象
setState({ ...state, name: 'Jane' }); // 会触发渲染

8. useState 定义对象状态的示例

javascript
const [user, setUser] = useState({ name: 'John', age: 30 });

const updateUserName = () => {
  setUser({ ...user, name: 'Jane' });
};

9. React 状态管理机制和渲染优化策略

React 的状态管理机制主要通过 useStateuseReducer 和全局状态管理库(如 Redux)来管理组件的状态。每当状态更新时,React 会重新渲染受影响的组件或子树。

React 的渲染优化策略包括:

  • 虚拟 DOM:React 在内存中维护一个虚拟 DOM,更新时将新旧虚拟 DOM 进行比较(Diff),并最小化实际 DOM 操作。

  • shouldComponentUpdate 和 React.memo:通过控制组件的更新逻辑,避免不必要的渲染。

  • React.lazy 和 Suspense:实现按需加载组件,减少初始渲染的负担。

10. 从 JS 底层数据类型在内存中的特性来解释对象或数组的更新

在 JavaScript 中,对象和数组是引用类型,变量存储的是对象或数组的内存地址,而不是值本身。直接修改对象或数组的属性值并不会改变其引用地址,React 无法检测到引用地址的变化,因此不会触发重新渲染。

11. 浏览器访问服务器的链路和过程

当你在浏览器输入服务器的 IP 和端口访问网站时,经历的过程包括:

  1. DNS 解析:将域名解析为服务器的 IP 地址。

  2. TCP 连接:客户端通过三次握手与服务器建立 TCP 连接。

  3. 发送 HTTP 请求:客户端通过 TCP 连接发送 HTTP 请求到服务器。

  4. 服务器处理请求:服务器处理请求,生成响应内容。

  5. 返回 HTTP 响应:服务器将响应数据通过 TCP 连接发送回客户端。

  6. 浏览器渲染页面:浏览器解析响应的 HTML、CSS 和 JavaScript,生成并渲染页面。

  7. 资源加载:浏览器解析 HTML 文件时,可能会遇到 CSS、JS、图片等资源链接,浏览器会发起新的 HTTP 请求来获取这些资源,并继续渲染页面。

Copyright © 2024-present LofiSu