redux-ui

615 阅读3分钟

redux-ui官方


概述

将redux-ui视为UI状态的块级范围。每个块范围代表一个组件,每个变量代表一个UI状态键。


范围

用redux-ui @ui()装饰器包装您的根组件。它为临时UI变量赋予了新的范围,该范围是:

  • 自动绑定到 this.props.ui
  • 自动传递给@ui()装饰器包装的所有子组件
  • 将在componentWillUnmount上自动重置(可通过选项预防)
  • 可以通过道具手动重置
  • @ui()装饰器中的任何子组件更新


使用步骤

Step 1: 将redux-ui的 reducer 添加到 redux的 store中

import { reducer as uiReducer } from 'redux-ui'
// ...
combineReducers({ ...yourReducers, ui: uiReducer })


Step 2: 在每个“场景”或 父组件中,使用key 添加UI装饰器到来保存所有状态

import ui from 'redux-ui';

@ui({
  state: {
    yourVars: 'withDefaults',
    filters: []
  }
})
class YourComponent extends React.Component {
}


Step3:在每个子组件中使用基本@ui()装饰器;它将自动读取UI状态并将其写入父组件的UI键。

用法

@ui装饰器注入4个参数到你的组件:

  1. uiKey:从装饰器(例如,“ some-decorator” @ui('some-decorator')
  2. ui:组件的UI状态 uiKey
  3. updateUI:接受名称/值对或对象的函数,用于更新内部状态 uiKey
  4. resetUI:将状态重置为uiKey默认值的功能


装饰器将设置指定的任何默认状态(请参见下文)。在componentWillUnmount整个状态下,uiKey将设置为undefined。您还可以通过调用resetUI(例如,在路由器更改时)破坏状态 。

  • 装饰器API
@ui({
  key: 'some-name',
  persist: true,
  state: {
    uiVar1: '',
    uiVar2: (props, state) => state.router.location.query.searchTerm
  },
  reducer: (state, action) => {
    switch(action.type) {
      case '@@reduxReactRouter/routerDidChange':
        if (action.payload.location.query.extra_filters) {
          return state.set('extraFilters', true);
        }
      }
      return state;
    }
  },
  mergeProps: () => ({}),
  options: {}
})
  • 非装饰器API
import ui from 'redux-ui';
// or ui = require('redux-ui').default;

class SomeComponent extends Component {
}

SomeComponentWithUI = ui({ key: 'some-name', state: { ... }})(SomeComponent);


参数描述


名称

类型

说明

key

string(默认为随机字符)

UI缩减器中用于存储所有状态的键的名称。允许您使用已知路径在重新选择中创建选择器,并允许进行persist以下设置

persist

bool(默认false)

如果此组件的UI状态应在之后保留,则设置为true componentWillUnmount。您还必须key为此组件显式定义一个,否则该组件将随机化键并在实例化时加载新的UI状态。

注意:所有父UI组件也需要将其设置为true才能生效。再次考虑块级作用域-如果退出父作用域,则所有子作用域也将脱离上下文。

state

object

需要在状态对象中显式定义所有UI变量。这使我们能够确定变量属于哪个作用域,因为作用域是在组件树中继承的。可以将其视为let在块作用域内使用


Examples

import ui from 'redux-ui';

@ui({
  state: {
    filter: (props, state) => state.router.location.query.filter,
    isFormVisible: true,
    isBackgroundRed: false
  }
})
class A extends Component {
  render() {
    return (
      <div>
        <pre><code>{ this.props.ui }</code></pre>

        // Render child B
        <B />
      </div>
    );
  }
}

@ui()
class B extends Component {
  render() {
    return <C />;
  }
}

@ui({
  state: {
    someChildProp: 'foo'
  }
})
class C extends Component {
  render() {
    return (
      <div>
        <p>I have my own UI state C and inherit UI state from B and A</p>
        <p>If I define variables which collide with B or A mine will
        be used, as it is the most specific context.</p>
    );
  }
}