npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@react-redux-ria/redux-list

v0.0.1-alpha.1

Published

redux-list ===

Downloads

2

Readme

redux-list

总览

基于redux的列表状态管理库,对列表的以下几个功能做了状态与行为的标准化封装:

  • 数据请求与展现
  • 数据项选择
  • 分页
  • 排序
  • 筛选

主要有以下三个模块:

listReducer: 列表reducer,根据列表的action信息,通知redux store做出相应的状态更新

listActionCreators: 列表action creators,提供相关的列表行为,派发对应的action

reduxList: 高阶组件创建函数,接受一个配置,返回一个封装了相关列表行为,同时通过props注入了列表状态和actionCreators的高阶组件

数据流

image

安装

npm install @react-redux-ria/redux-list 

基本使用方式

第一步:安装 list reducer

store需要知道如何处理来自列表组件的action,所以我们需要传入库提供的reducer

import { createStore, combineReducers } from 'redux'
import { reducer as listReducer } from 'redux-list'

const rootReducer = combineReducers({
  // ...其他reducer
  
  // 默认用list作为属性名,需要自定义属性名,可以在reduxList处传入selector,告诉list reducer如何获取列表状态
  list: listReducer
})

const store = createStore(rootReducer)

第二步:创建并使用列表高阶组件

为了使得列表组件能够连接到store,需要通过 reduxList 函数包裹一层。高阶组件会通过props注入listData和list两个属性完成列表的一系列行为。

listData是一个ListState数据结构,包含着当前列表的状态信息,list则是ListActionCreators数据结构,是列表的actionCreators方法(行为)集合。

大多数情况下,reduxList只需要传入list和fetcher两个配置项,fetcher是一个符合Fetcher数据结构的列表数据获取函数。

以下以antd为例创建列表组件:

import React, {PureComponent} from 'react';
import ReactDOM from 'react-dom';
import reduxList from 'redux-list';
import {Table} from 'antd';

const tableFields = [
  {
    title: '姓名',
    dataIndex: 'name',
    key: 'name',
    sorter: true,
    filters: [
      {text: 'Joe', value: 'Joe'},
      {text: 'Jim', value: 'Jim'}
    ],
    filterMultiple: false
  },
  {
    title: '年龄',
    dataIndex: 'age',
    key: 'age',
    sorter: true,
    filters: [
      {text: '10', value: 10},
      {text: '11', value: 11}
    ],
  }
];

@reduxList({
  // 列表唯一标识
  list: 'myList',
  // fetcher函数 
  fetcher(query) => ({
    results: [{age: 10, name: 'name1'}, {age: 11, name: 'name2'}]
  }),
  // 列表集合选择器,默认为 state => state.list
  selector: state => state.list
})
export default class ListTable extends PureComponent {

  onSelect = keys => this.props.list.updateSelections(keys);

  onChange = (pagination, filters, {field, order}) => {
    const sort = {field, order};
    this.props.list.fetch({
      page: pagination,
      sort: [sort],
      filters
    });
  };

  // 自定义布局
  render() {
    const data = this.props.listData;
    const rowSelection = {
      selectedRowKeys: data.selections,
      onChange: this.onSelect
    };

    const pagination = data.pager
      ? {
        ...data.pager,
        showTotal: (total, range) => `共 ${total} 记录`
      }
      : false;

    return (
      <div className="my-list">
        <Table
          rowKey="id"
          dataSource={data.results}
          columns={tableFields}
          rowSelection={rowSelection}
          pagination={pagination}
          loading={data.loading}
          onChange={this.onChange}
        />
      </div>
    );
  }
}

ReactDOM.render(<ListTable />, document.body);

主要数据结构

// 分页数据结构
type Pager = { current?: number, pageSize?: number, total?: number };

// 排序数据结构
type Sort = Array<{ field: string, order: 'descend' | 'ascend' }>;

// 筛选数据结构
type Filters = { [field: string]: any };

// 列表查询
type ListQuery = { filters?: Filters, page?: Pager, sort?: Sort };

// 列表结果
type ListResult = { results: Array<any>, total: number, current?: number};

// 数据获取函数
type Fetcher = (query: ListQuery) => Promise<ListResult>;

// 列表状态
type ListState = {
  results: Array<any>, // 列表结果
  selections: Array<any>, // 列表选中项
  loading: boolean, // 是否加载中
  pager?: Pager, // 分页信息
  filters?: Filters, // 筛选信息
  sort?: Sort // 排序信息
};

type Action = {
  type: string,
  payload: any,
  meta?: { [filed: string]: any },
  error?: boolean
}

// 列表actionCreators
type ListActionCreators = {
  fetch: (query: ListQuery) => Function,
  updateResults: (results: any[]) => Function,
  updateSelections: (selections: any[]) => Action,
  updatePager: (page: Pager) => Action,
  updateFilters: (filters: Filters) => Action,
  updateSort?: (sort: Sort) => Action
}