implement context-based container

This commit is contained in:
AllenFang 2018-05-13 16:13:06 +08:00
parent 0ff0c33aa9
commit 906180ad3f
4 changed files with 113 additions and 73 deletions

View File

@ -1,5 +1,5 @@
import BootstrapTable from './src/bootstrap-table';
import withDataStore from './src/container';
import withContext from './src/contexts';
export default withDataStore(BootstrapTable);
export default withContext(BootstrapTable);

View File

@ -1,71 +0,0 @@
/* eslint no-return-assign: 0 */
/* eslint react/prop-types: 0 */
import React, { Component } from 'react';
import Store from './store';
import withSort from './sort/wrapper';
import withSelection from './row-selection/wrapper';
import remoteResolver from './props-resolver/remote-resolver';
import _ from './utils';
const withDataStore = Base =>
class BootstrapTableContainer extends remoteResolver(Component) {
constructor(props) {
super(props);
this.store = new Store(props.keyField);
this.store.data = props.data;
this.wrapComponents();
}
componentWillReceiveProps(nextProps) {
this.store.setAllData(nextProps.data);
}
wrapComponents() {
this.BaseComponent = Base;
const { pagination, columns, filter, selectRow, cellEdit } = this.props;
if (pagination) {
const { wrapperFactory } = pagination;
this.BaseComponent = wrapperFactory(this.BaseComponent, {
remoteResolver
});
}
if (columns.filter(col => col.sort).length > 0) {
this.BaseComponent = withSort(this.BaseComponent);
}
if (filter) {
const { wrapperFactory } = filter;
this.BaseComponent = wrapperFactory(this.BaseComponent, {
_,
remoteResolver
});
}
if (cellEdit) {
const { wrapperFactory } = cellEdit;
this.BaseComponent = wrapperFactory(this.BaseComponent, {
_,
remoteResolver
});
}
if (selectRow) {
this.BaseComponent = withSelection(this.BaseComponent);
}
}
render() {
const baseProps = {
...this.props,
store: this.store
};
return (
<this.BaseComponent { ...baseProps } />
);
}
};
export default withDataStore;

View File

@ -0,0 +1,35 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default () => {
const DataContext = React.createContext();
class DataProvider extends Component {
static propTypes = {
data: PropTypes.array.isRequired,
children: PropTypes.node.isRequired
}
state = { data: this.props.data };
componentWillReceiveProps(nextProps) {
this.setState(() => ({ data: nextProps.data }));
}
render() {
return (
<DataContext.Provider
value={ {
data: this.state.data
} }
>
{ this.props.children }
</DataContext.Provider>
);
}
}
return {
Provider: DataProvider,
Consumer: DataContext.Consumer
};
};

View File

@ -0,0 +1,76 @@
/* eslint no-return-assign: 0 */
/* eslint react/prop-types: 0 */
import React, { Component } from 'react';
// import Store from './store';
// import withSort from './sort/wrapper';
// import withSelection from './row-selection/wrapper';
import createDataContext from './data-context';
import createSortContext from './sort-context';
import createSelectionContext from './selection-context';
import remoteResolver from '../props-resolver/remote-resolver';
const withContext = (Base) => {
let DataContext;
let SelectionContext;
let SortContext;
return class BootstrapTableContainer extends remoteResolver(Component) {
constructor(props) {
super(props);
DataContext = createDataContext(this.props.data);
SelectionContext = createSelectionContext();
SortContext = createSortContext();
}
render() {
const { keyField, columns, remote } = this.props;
const baseProps = { keyField, columns, remote };
return (
<DataContext.Provider data={ this.props.data }>
<DataContext.Consumer>
{
dataProps => (
<SelectionContext.Provider
{ ...baseProps }
selectRow={ this.props.selectRow }
data={ dataProps }
>
<SelectionContext.Consumer>
{
selectionProps => (
<SortContext.Provider
{ ...baseProps }
defaultSorted={ this.props.defaultSorted }
defaultSortDirection={ this.props.defaultSortDirection }
data={ dataProps }
>
<SortContext.Consumer>
{
sortProps => (
<Base
{ ...this.props }
{ ...dataProps }
{ ...selectionProps }
{ ...sortProps }
/>
)
}
</SortContext.Consumer>
</SortContext.Provider>
)
}
</SelectionContext.Consumer>
</SelectionContext.Provider>
)
}
</DataContext.Consumer>
</DataContext.Provider>
);
}
};
};
export default withContext;