React系列之框架特点和组件类型

文章目录

React

MVC MVP MVVM

Web设计模式,通过分离模块来改进代码的组织方式。

MVC 是 Model View Controller 的缩写。

  • Model:模型层,数据相关的操作。
  • View:视图层,用户界面渲染逻辑。
  • Controller:控制器,数据模型和视图之间通信的桥梁。

MVC 模型把视图渲染和数据处理做了隔离,通过控制器接收视图操作,传递给数据模型,数据处理后由数据模型驱动视图渲染。

MVP 是 Model View Presenter 的缩写,可以说是 MVC 模式的改良。

  • Model、View依然负责数据和视图

如果 Model 只想做数据相关的操作,把通知 View 的逻辑挪到了 Control 里,这时 Control 摇身一变称为了 Presenter。因为解耦了 Model 和 View,也使得它们的职责划分更加清晰。

MVVM 是 Model View - ViewModel 的缩写,ViewModel 主要靠 DataBinding 把 View 和 Model 做了自动关联,框架替应用开发者实现数据变化后的视图更新。

MVVM与MVC最大的区别:实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变。

React 并不是严格意义上 MVC MVVM 这种前端架构模式,它更像一种视图层的库。在传统的 MVC、MVP、MVVM 等架构模式中,通常会将应用程序的逻辑分成不同的部分,比如模型(Model)、视图(View)和控制器(Controller)、展示器(Presenter)或视图模型(ViewModel)等,每个部分都有不同的职责和作用。而在 React 中,它更倾向于将界面拆分成多个可重用的组件,每个组件负责管理自己的状态和 UI,而不是像传统的架构模式那样严格分离模型和视图。

但它仍然可以与这些模式结合使用。例如,可以将 React 组件作为视图层,结合其他库或框架来管理应用程序的模型和控制器逻辑。

Vue.js 更偏向于模型-视图-视图模型(MVVM),但并不是严格遵循,而是借鉴并结合自己的特点。

单/双向数据绑定

单向数据绑定:Model 的更新会触发 View 的更新,View 的更新不会触发 Model 的更新,它们的作用是单向的。

双向数据绑定:Model 的更新会触发 View 的更新,View 的更新也会触发 Model 的更新,它们的作用是相互的

React 是单向数据绑定,当用户访问 View 时,通过触发 Events 进行交互,而在相应 Event Handlers 中,会触发对应的 Actions,而 Actions 通过调用 setState 方法对 View 的 State 进行更新,State 更新后会触发 View 的重新渲染。可以看出,在 React 中,View 层是不能直接修改 State,必须通过相应的 Actions 来进行操作。

Vue 支持单向数据绑定和双向数据绑定

  • 单向数据绑定:使用v-bind属性绑定、v-on事件绑定或插值形式{{data}}。
  • 双向数据绑定:使用v-model指令,用户对View的更改会直接同步到Model。

双向绑定的优缺点:

优点:比较方便简单。

缺点:属于暗箱操作,无法很好的追踪数据变化。

React 和 Vue 都只是单向数据流,虽然 Vue 有双向数据绑定,但是 Vue 父子组件之间数据传递仍然遵循单向数据流。

React特点

React 是一个用于构建用户界面的 JS 库。React 起源于 Facebook 的内部项目,用来架设 Instagram 网站,并于 2013 年 5 月开源。

特点:

  • 遵循组件设计模式
  • 使用虚拟DOM来高效操作DOM
  • 实现了单向响应数据流
  • JSX 是 JavaScript 语法的扩展, 可以直接在 JS 中写 XML 语法。

JSX

JSX即Javascript XML,它是对JS的语法扩展,可以直接在JS中写XML语法,JSX会将类似XML的语法转化为原生的JS。要在JSX中执行JS,需要写在{}中。

为了使浏览器能够读取 JSX,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。

JSX 结构最终会被翻译为 React.createElement 的结构。

组件和不同类型

React 中一切都是组件,我们通常将应用程序的整个逻辑分解为小的单个部分,每个单独的部分称为组件。

组件类型:

按状态分为无状态组件和有状态组件:

无状态组件也被称为"纯函数组件",就是不维护自己的state,只负责接收props渲染DOM。

对于这种无状态的组件,使用函数式的方式声明,会使得代码的可读性更好,并能大大减少代码量。

注:函数组件没有生命周期。(React Hooks 提供了一种在无需编写 class 的情况下使用 state 和其他 React 特性的方式。Hooks 使得在函数组件中引入和复用 state、生命周期方法等)

复制代码
const Todo = (props) => ( 
    <div onClick={props.onClick}>{props.text}</div> 
)

有状态组件就是组件内部包含状态 state。有状态组件通常会带有生命周期lifecycle,用以在不同的时刻触发状态的更新。

复制代码
class Hello extends React.Component{
  constructor(props){
    super(props);
    this.state = { 
      tips: "Hello World!"
    }
  }
  componentDidMount() {
    console.log("ComponentDidMount", this);
  }
  render() {
    return (
      <div>{this.state.tips}</div>
    );
  }

应用场景:无状态组件更加简单,适用于展示性组件(比如图片等不需要存数据的),而有状态组件更适合处理复杂逻辑、数据管理和需要内部状态的情况。

按受控可以分为受控组件和非受控组件,主要场景是在表单中:

受控组件:表单元素的值(例如输入框、复选框、下拉框等)由 React 组件的 state 来管理,通过事件处理函数来更新 state,并将 state 的值绑定到表单元素的 value 属性。

复制代码
import React, { useState } from 'react';

function ControlledComponent() {
  const [inputValue, setInputValue] = useState('');

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

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

非受控组件:在非受控组件中,表单元素的值不受 React state 的控制,而是由 DOM 元素自身来管理。通常是通过 ref 来获取表单元素的引用,然后直接在原生 DOM 元素上操作。

复制代码
function UncontrolledCompenent() {
    const inputRef = useRef();
    
    const handleClick = () => {
        alert(`Input value: ${inputRef.current.value}`);
    }
    
    return (
        <div>
            <input type="text" ref={inpuutRef} />
            <button onClick={handleClick}>Get Input Value</button>
        </div>
    )
}

应用场景:受控组件适用于需要对表单元素进行更细粒度控制、数据验证和处理的场景。非受控组件适用于一些简单的场景,或者需要直接操作 DOM 的情况。可能会减少一些状态管理的复杂性,但也失去了 React 组件对数据流的控制。

Container Components 容器组件和 Components 展示组件/UI组件:

容器组件主要负责数据逻辑和状态管理。包含业务逻辑,例如处理用户输入、发起网络请求等。通常是 class 组件,因为它们需要使用 state 和生命周期方法。

展示组件仅负责 UI 渲染,不处理数据逻辑。接收容器组件传递的数据和回调函数,并将其渲染为用户界面。可以是函数组件或纯函数组件。

通过将容器组件和展示组件分开,我们可以实现代码的分层和逻辑的解耦,使得代码更加清晰和易于维护。

todo

高阶组件(HOC):

高阶组件是将组件作为参数并生成另一个组件的函数。可以提高代码的复用性和灵活性。

高阶组件是装饰器模式在 React 中的实现。

应用例子:

复制代码
对每个页面做权限控制,若是符合权限则正常渲染页面,不符合则渲染No Role Page. 希望在一个地方统一做权限控制处理

export const withAuth = (WrappedComponent) => {
  const WithAuth = (props) => {
    const { role } = props;
    const currentRole = async () => {
      return await gotRole();
    };
    const [isAdmin, setIsAdmin] = useState(false);
    useEffect(() => {
      if (role === currentRole) {
        setIsAdmin(true);
      }
    }, [role]);
    return isAdmin ? <WrappedComponent {...props} /> : <div>No Role</div>;
  };
  return WithAuth;
};
相关推荐
黄智勇12 分钟前
xlsx-handlebars 一个用于处理 XLSX 文件 Handlebars 模板的 Rust 库,支持多平台使
前端
brzhang1 小时前
为什么 OpenAI 不让 LLM 生成 UI?深度解析 OpenAI Apps SDK 背后的新一代交互范式
前端·后端·架构
brzhang2 小时前
OpenAI Apps SDK ,一个好的 App,不是让用户知道它该怎么用,而是让用户自然地知道自己在做什么。
前端·后端·架构
水冗水孚2 小时前
React中使用map+area标签实现img图片特定区域标记功能(可用Photoshop精准拾取对应点位)
react.js·html·photoshop
井柏然3 小时前
前端工程化—实战npm包深入理解 external 及实例唯一性
前端·javascript·前端工程化
IT_陈寒3 小时前
Redis 高性能缓存设计:7个核心优化策略让你的QPS提升300%
前端·人工智能·后端
井柏然3 小时前
从 npm 包实战深入理解 external 及实例唯一性
前端·javascript·前端工程化
羊锦磊4 小时前
[ vue 前端框架 ] 基本用法和vue.cli脚手架搭建
前端·vue.js·前端框架
brzhang4 小时前
高通把Arduino买了,你的“小破板”要变“AI核弹”了?
前端·后端·架构
她说..4 小时前
通过git拉取前端项目
java·前端·git·vscode·拉取代码