乐趣区

关于react.js:3个容易混淆的前端框架概念

大家好,我卡颂。

有 3 个容易混同的前端框架概念:

  1. 响应式更新
  2. 单向数据流
  3. 双向数据绑定

在持续浏览本文前,读者能够思考下是否明确晓得三者的含意。

这三者之所以容易混同,是因为他们尽管同属前端框架领域内的概念,但又不是同一形象层级的概念,不好间接比拟。

本文会从 3 个形象层级动手解说这三者的区别。

欢送退出人类高质量前端交换群,带飞

响应式更新

响应式更新 也叫 细粒度更新 。同时,最近前端圈比拟火的Signal 这一概念形容的也是 响应式更新

抽象的讲,响应式更新 形容的是 状态与 UI 之间的关系 ,即 状态变动如何映射到 UI 变动

思考如下例子(例子来自 what are signals 一文):

function TodoApp() {const [todos, setTodos] = useState([{ text: 'sleep', completed: false}]
    )
    
    const [showCompleted, setShowCompleted] = useState(false)
    
    const filteredTodos = useMemo(() => {return todos.filter((todo) => !todo.completed || showCompleted)
    }, [todos, showCompleted])

    return (<TodoList todos={filteredTodos} />
    )
}

TodoApp 组件中,定义了两个状态:

  • 待办事项todos
  • 是否展现实现的事项showCompleted

以及根据上述状态派生出的状态 filteredTodos。最终,返回<TodoList/> 组件。

如果 todos 状态变动,UI该如何变动?即 咱们该如何晓得状态变动的影响范畴?这时,有两个思路:

  • 推(push
  • 拉(pull

推的原理

咱们能够从变动的状态(例子中为todos)登程,依据状态的派生关系,一路推下去。

在例子中:

  1. todos变动
  2. filteredTodostodos 派生而来,变动传导到他这里
  3. <TodoList/>组件依赖了filteredTodos,变动传导到他这里
  4. 确定了 todos 变动的最终影响范畴后,更新对应UI

这就建设了 状态与 UI 之间的关系

除了 之外,还有一种被称为 的形式。

拉的原理

同样的例子,咱们也能建设 状态与可能的 UI 变动的关系 ,再反过来推导UI 变动的范畴。

在例子中:

  1. todos变动
  2. 可能有 UI 变动(因为建设了 状态与可能的 UI 变动的关系
  3. UI<TodoList/> 组件相干,判断他是否变动
  4. <TodoList/>组件依赖 filteredTodosfilteredTodostodos派生而来,所以 filteredTodos 是变动的
  5. 既然 filteredTodos 变动了,那么 <TodoList/> 组件可能变动
  6. 计算变动的影响范畴,更新UI

在支流框架中,React的更新以 为主,VuePreactSolid.js等更多框架应用 的形式。

本文聊的 响应式更新 就是 这种形式的一种实现。

单向数据流

咱们能够发现,不论是 还是 ,他们都须要计算变动的影响范畴,即 一个状态变动后,到底有多少组件会受影响

那么,从框架作者的角度登程,是心愿减少一些束缚,来缩小 计算影响范畴 这一过程的复杂度。

同样,从框架使用者的角度登程,也心愿减少一些束缚,当 计算影响范畴 bug后,更容易排查问题。

这就有了 单向数据流

单向数据流 是一条约定,他规定了 当状态变动后,变动产生的影响只会从上往下传递

思考如下例子:

function Parent() {const [num] = useState(0);
  return <Child data={num}/>;
}

function Child({data}) {
  const isEven = data % 2 === 0;
  return <GrandChild data={isEven}/>;
}

function GrandChild({data}) {return <p>{data}</p>;
}

<Parent/>组件的状态 num 作为 props 传给 <Child/> 组件,再作为 props 传给 <GrandChild/> 组件,整个过程只能自上而下。

单向数据流 并不是实现前端框架必须遵循的准则,他的存在次要是为了缩小开发者的心智累赘,让 状态变动后,计算影响范畴 这一过程更可控。

双向数据绑定

当本文开篇聊 响应式更新 时,探讨的是 状态与 UI 的关系,这是将框架作为一个整体来探讨,形象层级比拟高。

当咱们持续聊到 单向数据流 时,探讨的是 状态变动的影响范畴在组件间单向扩散 ,这是 组件与组件之间的关系,形象层级降落了一级。

接下来咱们要探讨的 双向数据绑定,探讨的是单个组件内产生的事。

双向数据绑定 状态 + 扭转状态后触发的回调 相结合的语法糖。

这里不探讨框架语境下「语法糖」一词是否齐全精确

比拟出名的 双向数据绑定 实现,比方 Vue 中的 v-model 语法:

<input v-model=‘data’/>

相当于如下状态 + 事件回调的组合:

<input @input='onInput' :value=‘data’/>

实际上晚期 React 中也有相似实现,名叫 LinkedStateMixin,只是早已被废除

总结

咱们能够用一张图概括本文介绍的 3 个概念之间的关系:

概括起来次要是两点:

  • 他们都是前端框架领域内的概念
  • 他们属于不同形象层级的概念

其中:

  • 双向数据绑定 形容的是 组件内逻辑与视图的关系
  • 单向数据流 形容的是 组件之间的关系
  • 响应式更新 形容的是 状态与 UI 之间的关系
退出移动版