All Projects → blackChef → rce

blackChef / rce

Licence: other
rce stands for react, data cursor, elm, is a lightweight react architecture.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to rce

archi-modelrepository-plugin
coArchi - a plug-in to share and collaborate on Archi models.
Stars: ✭ 104 (+642.86%)
Mutual labels:  architecture
fyi
Map & Explore your organization's System Architecture
Stars: ✭ 28 (+100%)
Mutual labels:  architecture
asl-interpreter
Example implementation of Arm's Architecture Specification Language (ASL)
Stars: ✭ 78 (+457.14%)
Mutual labels:  architecture
SherwoodArch
The Sherwood Architecture is a custom 64-Bit RISC based CPU architecture.
Stars: ✭ 13 (-7.14%)
Mutual labels:  architecture
Perfect-Server-Side-Swift iOS-App
A family tree API server implementation with iOS client. Server has been implemented with Perfect: Server-Side Swift And iOS client is in pure Swift.
Stars: ✭ 15 (+7.14%)
Mutual labels:  architecture
ddd-example-ecommerce
Domain-driven design example in Java with Spring framework
Stars: ✭ 73 (+421.43%)
Mutual labels:  architecture
XNU
Research into porting the XNU kernel to ARM devices.
Stars: ✭ 76 (+442.86%)
Mutual labels:  architecture
top-software-engineering-articles
Collection of top articles about great software engineering practices.
Stars: ✭ 45 (+221.43%)
Mutual labels:  architecture
Archangels
Entry to the O'Reilly Autumn 2021 Architectural Kata
Stars: ✭ 16 (+14.29%)
Mutual labels:  architecture
landscape-of-programming
This repo aim to show you what to learn on the way to excellence.
Stars: ✭ 67 (+378.57%)
Mutual labels:  architecture
react-mvp
Model-View-Presenter Proof of Concept in React
Stars: ✭ 38 (+171.43%)
Mutual labels:  architecture
RouterService
💉Type-safe Navigation/Dependency Injection Framework for Swift
Stars: ✭ 212 (+1414.29%)
Mutual labels:  architecture
silky
The Silky framework is designed to help developers quickly build a microservice development framework through simple code and configuration under the .net platform.
Stars: ✭ 146 (+942.86%)
Mutual labels:  architecture
Paper-Reading-List
rearch.github.io
Stars: ✭ 15 (+7.14%)
Mutual labels:  architecture
golang-starter
Golang code boilerplate inspired by clean architecture
Stars: ✭ 49 (+250%)
Mutual labels:  architecture
documentation
🍰 Architectural design methodology for Frontend projects
Stars: ✭ 359 (+2464.29%)
Mutual labels:  architecture
SearchMovies
sample Android Application using MVP pattern
Stars: ✭ 47 (+235.71%)
Mutual labels:  architecture
Coding-Standards
Coding Guidelines for C#
Stars: ✭ 125 (+792.86%)
Mutual labels:  architecture
c4-diagrams.net
The EasyC4 library is for quick and convenient visualising software architecture in diagrams.net / draw.io application using the C4 model approach.
Stars: ✭ 28 (+100%)
Mutual labels:  architecture
flutter-clean-arch
A flutter's implementation of a "clean architecture"
Stars: ✭ 149 (+964.29%)
Mutual labels:  architecture

问题

  • 我们喜欢使用组件,因为组件将功能封装在内部,我们不需要了解细节,引入它就可以使用。
  • 我们喜欢开发组件,因为组件化能让我们一次专注于解决一个问题。
  • 我们喜欢 mvc 架构,因为我们总是会遇到让不同地方渲染相同的状态的场景。

但一个拥有本地状态,自己能控制状态更新的组件是没法和其他组件共享状态的。

让一个组件能把功能封装,做到即插即用的同时,又能被外界控制,能和其他组件共享状态,就是 rce 解决的问题。

rce

rce 代表 react, cursor, elm。是一个轻量级的 react 架构。它有以下几个特点:

  • 没有复杂的概念,没有复杂的代码。仅有两个 api,设计思路与 react 一致。会 react 就能快速上手 rce。
  • 利用数据指针,让你能把组件的 state 保存 app 的最上一层,但又能让将管理 state 的方法写在组件内部。
  • 每个组件都按下面的模式划分。 遵循这个受 elm 启发的模式,你就能轻易写出可高度复用的组件。
    • init: 定义组件的默认状态。
    • view: 渲染 model。发布 action。
    • update: 响应 view 传来的 action,修改 model。

查看这个教程。了解 rce 的设计理念和实现方式。

示例

安装

npm install rce-pattern --save
yarn add rce-pattern

参考

model, init, view, update

  • model: Cortex data。组件的 state 以 cortex data 保存和传递。
  • init: Function。返回组件的默认 model 的值。
  • view: React Component。
  • update:Function。update({ type, payload, model, dispatch, getLastetModel })
    • type: String。action 的类型。
    • payload: Any。dispatch 发来的信息。
    • model: Cortex Cursor。update 执行时,组件内的 model。
    • getLastetModel: Function。获取组件最新的 model。在异步处理的 callback 内应该用它来获取最新的 model。
    • dispatch: Function。可以在 update 内 dispatch 其他 action。

createComponent

createComponent({ name, view, update }) 一个 HOC,将 view 和 update 串联起来。

  • name: String, 非必须。组件的 displayName。有利于调试。
  • view: React Component,必须。
  • update: Function,非必须。

传入 createComponent 的组件收到 model, dispatch, dispatcher, 三个额外的 props。

  • model:Cortex data。
  • dispatch: Function。dispatch(type, payload)。发布一个 action。
    • type: String,必须。
    • payload:Any,非必须。
  • dispatcher: Function。dispatcher(type, arg)。dispatcher 返回一个执行 dispatch 的函数。
    • arg 为 undefine 时,返回 event => dispatch(type, event)
    • arg 为 Function 时,返回 event => dispatch(type, arg(event))
    • arg 为 其它时,返回 () => dispatch(type, arg)

createModelHolder

createModelHolder(view, arg)

  • arg 为函数时,用那个函数返回的值作为 view 的初始 model。
  • arg 为其他时,用 arg 作为 view 的初始 model。

快速开始

CortexJs

rce 采用 cortexjs 实现的数据指针。

Cortex is an immutable data store for managing deeply nested structure with React

考虑 model = { a: { foo: 5 }, b: 5 } 这样一个数据。 在将它创建成 cortex 数据之后:

  • 要读取 model.a.foo 的值,我们这么做:fooValue = model.a.foo.val()
  • 要修改 model.a.foo 的值。我们这么做:model.a.foo.set(10)

修改 cortex 数据的操作是异步的。当 cortex 数据更新时,rce 会自动渲染你的 view。就跟 react state 的工作方式一样。

A Counter

我们来编写一个 Counter 组件。在线例子:https://blackchef.github.io/rce/#/counter

import React from 'react';
import createComponent from 'rce-pattern/createComponent';

// name 用作 component 的 displayName, 有利于调试。
let name = 'counter';

// 一个函数,返回这个组件的初始状态。
let init = function() {
  return 0; // count
};

// 组件在其内部调用 dispatch 来发布 action。
// update 函数接收到 action,再根据不同的 action 以不同的方式更新组件的 model。
let update = function({ type, model }) {
  // update 只是一个函数。在 type 很多时,可以用各种各样的技巧来解决 too many ifs 的问题。
  if (type === 'increment') {
    // 这里用 set 和 val 两个函数来修改、读取 model 的值。
    model.set( model.val() + 1 );
  } else {
    model.set( model.val() - 1 );
  }
};

// view 是一个 react 组件。被 createComponent wrap 之后,它收到 model, dispatch, dispatcher 三个属性。
// model:Cortex Cursor。组件的 model,理解为组件的 state。
// dispatch(type, payload): dispatch 触发 action。
// dispatcher(type, arg): dispatcher 返回一个执行 dispatch 的函数。 有助于编写 function 形式的 react 组件
let view = function ({ model, dispatch, dispatcher }) {
  return (
    <div>
      <button type="button" onClick={dispatcher('increment')} >+</button>
      <span>{model.val()}</span>
      <button type="button" onClick={dispatcher('decrement')}>-</button>
    </div>
  );
};

// createComponent 将 view,update 二者串联起来。
view = createComponent({ name, update, view });
export { init, view };

Three Counters

现在我们利用之前的 Counter 组件,编写一个包含三个 Counter,其中一个独立,另外两个共享状态的新组件: ThreeCounters。 在线例子:https://blackchef.github.io/rce/#/threeCounters

import React from 'react';
import createComponent from 'rce-pattern/createComponent';
import { view as Counter, init as counterInit } from './counter';

let name = 'threeCounters';

let init = function() {
  return {
    // 一个父组件可以用子组件的 init 函数来生成子组件需要的 model。
    // 这时候它不需要管那个子组件需要的 model 是怎样的数据结构,有怎样的值。
    countA: counterInit(),

    // 父组件也能用其他值为子组件设定默认值。
    countBC: 1,
  };
};

// 因为 update 存在于组件自身内部,一个父组件可以简简单单的引入一个组件,那个组件本身就能工作。
// 又因为父组件可以接触到子组件的 model,父组件也可以在父一级对子组件进行控制。
let update = function({ model }) {
  // 只有一种 type 的 action。这时候就没必要对 type 进行判断。
  model.set( init() );
};

// 将 model 的子 model 传给不同的子组件。共享同一子 model 的组件会有相同的渲染。
let view = function ({ model, dispatch, dispatcher }) {
  return (
    <div>
      <section className="section">
        <h4>counterA</h4>
        <Counter model={model.countA} />
      </section>

      <section className="section">
        <h3>counterB and counterC share same model</h3>

        <section>
          <h4>counterB</h4>
          <Counter model={model.countBC} />
        </section>

        <section>
          <h4>counterC</h4>
          <Counter model={model.countBC} />
        </section>
      </section>

      <section className="section">
        <button
          type="button"
          onClick={dispatcher('reset')}
        >
          reset all
        </button>
      </section>
    </div>
  );
};

view = createComponent({ name, update, view });
export { init, view };

Model Holder

在 app 的最上层使用 createModelHolder,将整个 app 内的 model 都保存在这里。

import React from 'react';
import ReactDOM from 'react-dom';
import createModelHolder from 'rce-pattern/createModelHolder';
import { view as ThreeCounters, init as threeCountersInit } from './threeCounters';

// createModelHolder(view, init): 把 model 保存在 state 里。
let App = createModelHolder(ThreeCounters, threeCountersInit);

ReactDOM.render(
  <App/>
  document.querySelector('.appContainer')
);

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].