@hyder/component

1.5.2 • Public • Published

@hyder/component

提供一致的方式创建React模块和应用,让react应用开发更轻松。

基于@hyder/component的模块能够运行在hyder环境中, 其中的逻辑代码运行在js-core环境中, 也能够运行在普通的react应用中, 提升模块重用度,简化复杂模块的开发难度,特别适合团队开发。

开始使用

  1. 添加依赖
yarn add @hyder/component
  1. 创建组件

组件(如需要较复杂的逻辑)可由ViewModel组成, 在hyder中model 会运行在js-core环境中。

模块的开发方式和目录结构并无要求,但推荐如下:

- Counter/   # 模块
  - index.js   # 入口,如复杂的话可衍生出多个子组件
  - model.js   # 逻辑代码,框架本身不依赖于这个名称,逻辑复杂可加载其他文件。
  - style.scss # 样式

hyder babel插件会根据model中的注解加载model到js-core中(这个特性还在内部开发中)

模块目录和代码可参考Counter示例

借鉴于dva的最佳实践,model由state, reducers, 和effects组成。

model.js

export default {
  // state: { ... }
  state: props => ({ count: 0 }),  // 模块的state可由props初始化

  reducers: {
    up(state, action) {
      return nextState;
    },

    ...
  },

  effects: {
    * mount(action, { put, select }) {
      ...
      yield put({ type: 'load', payload: ... });
    }
  }
};

index.js

通过提供的withModel高阶组件来组合上面定义的model。

import { withModel } from '@hyder/component';   // 引入withModel
import model from './model.js';


const View = ({ count, dispatch }) => (
  <div>
    <div className="count">{count}</div>
    <div className="buttons">
      <button className="button" onClick={() => dispatch({ type: 'up', step: 3 })}>Up</button>
      <button className="button" onClick={() => dispatch({ type: 'down', step: 4 })}>Down</button>
    </div>
  </div>
);


export default withModel(model)(Counter);

对于react@16.8以上版本,可使用React Hooks集成model。

import { useModel } from '@hyder/component';
import model from './model';

const Counter = props => {
  const [{ count }, dispatch] = useModel(model);
  return (
    <div>
      <div className="count">{count}</div>
      <div className="buttons">
        <button className="button" onClick={() => dispatch({ type: 'up', step: 3 })}>Up</button>
        <button className="button" onClick={() => dispatch({ type: 'down', step: 4 })}>Down</button>
      </div>
    </div>
  );
};

接入到redux

配合react-redux可在应用级别使用, 无需依赖其他库,可方便集成到现有redux应用中。

接入

import { compose } from 'redux';
import { createStoreEnhancer } from '@hyder/component';   // 载入storeEnhancer

import pageModel from './models/page';  // 载入应用的模块,可以有多个


const hyderEnhancer = createStoreEnhancer();

const store = createStore(
  reducer,
  {},
  compose(
    applyMiddleware(promiseMiddleware),
    hyderEnhancer
  )
);

// 添加应用的模块
hyderEnhancer.add([
  pageModel
]);

使用

  1. model

model的编写和上述一致,多了name,和少了mount对生命周期的支持,因为应用级别的model不和某个具体的react组件绑定。

详情可见示例

// models/page.js

export default {
  name: 'page',    // 名称,在dispatch中作为名字空间

  state: {
    count: 0       // 初始state, 由于应用级model不和具体react组件关键,所以只是个普通对象
  },

  reducers: {
    up(state, action) {
      return nextState;
    }
  },

  effects: {
    * down(action, { put, select }){
      ...
    }
  }
};
  1. view

像正常的react-redux的方式使用就可以啦。

const enhance = connect(v => v);
const View = enhance(({ page, dispatch }) => (
  <div className="page-view">
    <h1>{page.title}</h1>
    <div>
      <div className="count">{page.count || 0}</div>
      <div className="buttons">
        <button className="button" onClick={() => dispatch({ type: 'page/up', step: 3 })}>Up</button>
        <button className="button" onClick={() => dispatch({ type: 'page/down', step: 4 })}>Down</button>
      </div>
    </div>
  </div>
));

Readme

Keywords

none

Package Sidebar

Install

npm i @hyder/component

Weekly Downloads

1

Version

1.5.2

License

MIT

Unpacked Size

69.9 kB

Total Files

14

Last publish

Collaborators

  • bencode
  • helijia
  • qhwa