Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

redux-connect

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

redux-connect - npm Package Compare versions

Comparing version 6.0.0 to 7.0.0

modules/components/AsyncConnect.js

48

lib/components/AsyncConnect.js

@@ -6,2 +6,6 @@ 'use strict';

var _jsx2 = require('babel-runtime/helpers/jsx');
var _jsx3 = _interopRequireDefault(_jsx2);
var _extends2 = require('babel-runtime/helpers/extends');

@@ -31,6 +35,10 @@

var _RouterContext = require('react-router/lib/RouterContext');
var _Route = require('react-router/Route');
var _RouterContext2 = _interopRequireDefault(_RouterContext);
var _Route2 = _interopRequireDefault(_Route);
var _renderRoutes = require('react-router-config/renderRoutes');
var _renderRoutes2 = _interopRequireDefault(_renderRoutes);
var _utils = require('../helpers/utils');

@@ -51,3 +59,3 @@

_this.state = {
propsToShow: _this.isLoaded() ? props : null
previousLocation: _this.isLoaded() ? null : props.location
};

@@ -71,4 +79,6 @@

AsyncConnect.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
var navigated = this.props.location !== nextProps.location;
// Allow a user supplied function to determine if an async reload is necessary
if (this.props.reloadOnPropsChange(this.props, nextProps)) {
if (navigated && this.props.reloadOnPropsChange(this.props, nextProps)) {
this.loadAsyncData(nextProps);

@@ -78,6 +88,2 @@ }

AsyncConnect.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
return this.state.propsToShow !== nextState.propsToShow;
};
AsyncConnect.prototype.componentWillUnmount = function componentWillUnmount() {

@@ -95,4 +101,7 @@ this.mounted = false;

var store = this.context.store;
var loadResult = (0, _utils.loadAsyncConnect)((0, _extends3.default)({}, props, { store: store }));
this.setState({ previousLocation: this.props.location });
// TODO: think of a better solution to a problem?

@@ -108,3 +117,3 @@ this.loadDataCounter += 1;

if (_this2.loadDataCounter === loadDataCounterOriginal && _this2.mounted !== false) {
_this2.setState({ propsToShow: props });
_this2.setState({ previousLocation: null });
}

@@ -120,5 +129,16 @@

AsyncConnect.prototype.render = function render() {
var propsToShow = this.state.propsToShow;
var _this3 = this;
return propsToShow && this.props.render(propsToShow);
var previousLocation = this.state.previousLocation;
var _props = this.props,
location = _props.location,
_render = _props.render;
return (0, _jsx3.default)(_Route2.default, {
location: previousLocation || location,
render: function render() {
return _render(_this3.props);
}
});
};

@@ -137,6 +157,8 @@

},
render: function render(props) {
return _react2.default.createElement(_RouterContext2.default, props);
render: function render(_ref) {
var routes = _ref.routes;
return (0, _renderRoutes2.default)(routes);
}
};
exports.default = AsyncConnect;

@@ -7,2 +7,6 @@ 'use strict';

var _withRouter = require('react-router/withRouter');
var _withRouter2 = _interopRequireDefault(_withRouter);
var _AsyncConnect = require('../components/AsyncConnect');

@@ -12,2 +16,4 @@

exports.default = (0, _reactRedux.connect)(null, { beginGlobalLoad: _store.beginGlobalLoad, endGlobalLoad: _store.endGlobalLoad })(_AsyncConnect.AsyncConnect);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = (0, _withRouter2.default)((0, _reactRedux.connect)(null, { beginGlobalLoad: _store.beginGlobalLoad, endGlobalLoad: _store.endGlobalLoad })(_AsyncConnect.AsyncConnect));

@@ -29,6 +29,5 @@ 'use strict';

var key = item.key;
if (!key) {
return item;
}
if (!key) return item;
return (0, _extends4.default)({}, item, {

@@ -35,0 +34,0 @@ promise: function promise(options) {

@@ -5,2 +5,6 @@ 'use strict';

var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');

@@ -25,6 +29,10 @@

exports.filterAndFlattenComponents = filterAndFlattenComponents;
exports.filterAndLayerComponents = filterAndLayerComponents;
exports.filterComponents = filterComponents;
exports.loadAsyncConnect = loadAsyncConnect;
exports.loadOnServer = loadOnServer;
var _matchRoutes = require('react-router-config/matchRoutes');
var _matchRoutes2 = _interopRequireDefault(_matchRoutes);
var _store = require('../store');

@@ -51,6 +59,7 @@

var length = iterable.length;
var results = new Array(length);
var i = 0;
return _promise2.default.resolve().then(function iterateOverResults() {
function iterateOverResults() {
return iterator(iterable[i], i, iterable).then(function (result) {

@@ -65,3 +74,5 @@ results[i] = result;

});
});
}
return iterateOverResults();
};

@@ -113,33 +124,18 @@

/**
* Returns an array of an array of components on the same layers that are wrapped
* Returns an array of components that are wrapped
* with reduxAsyncConnect
* @param {Array} components
* @param {Array} branch
* @return {Array}
*/
function filterAndLayerComponents(components) {
var layered = [];
var l = components.length;
function filterComponents(branch) {
return branch.reduce(function (result, _ref) {
var route = _ref.route,
match = _ref.match;
var _loop2 = function _loop2(i) {
var component = components[i];
if ((typeof component === 'undefined' ? 'undefined' : (0, _typeof3.default)(component)) === 'object') {
var keys = (0, _keys2.default)(component);
var componentLayer = [];
keys.forEach(function (key) {
if (component[key] && component[key].reduxAsyncConnect) {
componentLayer.push(component[key]);
}
});
if (componentLayer.length > 0) {
layered.push(componentLayer);
}
} else if (component && component.reduxAsyncConnect) {
layered.push([component]);
if (route.component && route.component.reduxAsyncConnect) {
result.push([route.component, { route: route, match: match }]);
}
};
for (var i = 0; i < l; i += 1) {
_loop2(i);
}
return layered;
return result;
}, []);
}

@@ -150,16 +146,18 @@

* and loads data
* @param {Object} data.components
* @param {Object} data.routes - static route configuration
* @param {String} data.location - location object e.g. { pathname, query, ... }
* @param {Function} [data.filter] - filtering function
* @return {Promise}
*/
function loadAsyncConnect(_ref) {
var _ref$components = _ref.components,
components = _ref$components === undefined ? [] : _ref$components,
_ref$filter = _ref.filter,
filter = _ref$filter === undefined ? function () {
function loadAsyncConnect(_ref2) {
var location = _ref2.location,
_ref2$routes = _ref2.routes,
routes = _ref2$routes === undefined ? [] : _ref2$routes,
_ref2$filter = _ref2.filter,
filter = _ref2$filter === undefined ? function () {
return true;
} : _ref$filter,
rest = (0, _objectWithoutProperties3.default)(_ref, ['components', 'filter']);
} : _ref2$filter,
rest = (0, _objectWithoutProperties3.default)(_ref2, ['location', 'routes', 'filter']);
var layered = filterAndLayerComponents(components);
var layered = filterComponents((0, _matchRoutes2.default)(routes, location.pathname));

@@ -172,36 +170,35 @@ if (layered.length === 0) {

// cycle
return mapSeries(layered, function (componentArr) {
if (componentArr.length === 0) {
return mapSeries(layered, function (_ref3) {
var component = _ref3[0],
routeParams = _ref3[1];
if (component == null) {
return _promise2.default.resolve();
}
// Collect the results of each component on current layer.
// Collect the results of each component
var results = [];
var asyncItemsArr = [];
var asyncItems = component.reduxAsyncConnect;
asyncItemsArr.push.apply(asyncItemsArr, asyncItems);
var _loop3 = function _loop3(i) {
var component = componentArr[i];
var asyncItems = component.reduxAsyncConnect;
asyncItemsArr.push.apply(asyncItemsArr, asyncItems);
// get array of results
results.push.apply(results, asyncItems.reduce(function (itemsResults, item) {
if (filter(item, component)) {
var promiseOrResult = item.promise((0, _extends3.default)({}, rest, routeParams, {
location: location,
routes: routes
}));
// get array of results
results.push.apply(results, asyncItems.reduce(function (itemsResults, item) {
if (filter(item, component)) {
var promiseOrResult = item.promise(rest);
if (isPromise(promiseOrResult)) {
promiseOrResult = promiseOrResult.catch(function (error) {
return { error: error };
});
}
itemsResults.push(promiseOrResult);
if (isPromise(promiseOrResult)) {
promiseOrResult = promiseOrResult.catch(function (error) {
return { error: error };
});
}
return itemsResults;
}, []));
};
itemsResults.push(promiseOrResult);
}
for (var i = 0; i < componentArr.length; i += 1) {
_loop3(i);
}
return itemsResults;
}, []));

@@ -208,0 +205,0 @@ return _promise2.default.all(results).then(function (finalResults) {

{
"name": "redux-connect",
"version": "6.0.0",
"version": "7.0.0",
"description": "It allows you to request async data, store them in redux state and connect them to your react component.",

@@ -8,3 +8,3 @@ "main": "lib/index.js",

"type": "git",
"url": "git+ssh://git@github.com/makeomatic/redux-connect.git"
"url": "https://github.com/makeomatic/redux-connect"
},

@@ -14,5 +14,6 @@ "scripts": {

"lint": "eslint ./modules",
"test": "npm run lint && jest",
"pretest": "yarn lint",
"test": "jest",
"postversion": "npm publish && git push && git push --tags",
"prepublish": "npm run lint && npm run build"
"prepublish": "yarn lint && yarn build"
},

@@ -26,3 +27,3 @@ "keywords": [

],
"author": "Vitaly Aminev <v@makeomatic.ru>",
"author": "Vitaly Aminev <v@makeomatic.ca>",
"contributors": [

@@ -37,6 +38,7 @@ "Rodion Salnik (http://brocoders.com)"

"peerDependencies": {
"prop-types": "~15.x.x || ~16.x.x",
"prop-types": "15.x.x || 16.x.x",
"react": "16.x.x",
"react-redux": "~5.x.x",
"react-router": "~3.x.x"
"react-redux": "5.x.x",
"react-router": "4.x.x",
"react-router-config": "1.x.x || ^1.0.0-beta"
},

@@ -46,4 +48,4 @@ "devDependencies": {

"babel-core": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-jest": "^21.2.0",
"babel-eslint": "^8.1.2",
"babel-jest": "^22.0.4",
"babel-plugin-transform-runtime": "^6.15.0",

@@ -54,12 +56,12 @@ "babel-preset-es2015": "^6.18.0",

"babel-preset-stage-0": "^6.16.0",
"bluebird": "^3.4.6",
"enzyme": "^3.0.0",
"enzyme-adapter-react-16": "^1.0.0",
"eslint": "^4.8.0",
"eslint-config-airbnb": "^15.1.0",
"bluebird": "^3.5.1",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"eslint": "^4.14.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "5.x.x",
"eslint-plugin-jsx-a11y": "6.0.3",
"eslint-plugin-react": "^7.4.0",
"immutable": "^3.8.1",
"jest-cli": "^21.2.1",
"jest-cli": "^22.0.4",
"prop-types": "^15.6.0",

@@ -70,7 +72,8 @@ "raf": "^3.3.2",

"react-redux": "^5.0.6",
"react-router": "3.x.x",
"react-router": "4.x.x",
"react-router-config": "^1.0.0 || ^1.0.0-beta",
"react-test-renderer": "^16.0.0",
"redux": "^3.7.2",
"redux-immutable": "^4.0.0",
"sinon": "^4.0.0"
"sinon": "^4.1.3"
},

@@ -90,3 +93,7 @@ "dependencies": {

]
}
},
"files": [
"modules/",
"lib/"
]
}

@@ -31,7 +31,8 @@ ReduxConnect for React Router

```js
import { Router, browserHistory } from 'react-router';
import BrowserRouter from 'react-router-dom/BrowserRouter'
import renderRoutes from 'react-router-config/renderRoutes'
import { ReduxAsyncConnect, asyncConnect, reducer as reduxAsyncConnect } from 'redux-connect'
import React from 'react'
import { hydrate } from 'react-dom'
import { createStore, combineReducers } from 'redux';
import { createStore, combineReducers } from 'redux'

@@ -41,3 +42,3 @@ // 1. Connect your data, similar to react-redux @connect

key: 'lunch',
promise: ({ params, helpers }) => Promise.resolve({ id: 1, name: 'Borsch' })
promise: ({ match: { params }, helpers }) => Promise.resolve({ id: 1, name: 'Borsch' })
}])

@@ -47,5 +48,9 @@ class App extends React.Component {

// 2. access data as props
const lunch = this.props.lunch
const { lunch, route } = this.props
return (
<div>{lunch.name}</div>
<div>
{lunch.name}
{renderRoutes(route.routes)}
</div>
)

@@ -55,11 +60,29 @@ }

// 3. Connect redux async reducer
const store = createStore(combineReducers({ reduxAsyncConnect }), window.__data);
class Child extends React.component {
render() {
return (
<div>{'child component'}</div>
)
}
}
// 4. Render `Router` with ReduxAsyncConnect middleware
const routes = [{
path: '/',
component: App,
routes: [{
path: '/child',
exact: true,
component: Child,
}]
}]
// 2. Connect redux async reducer
const store = createStore(combineReducers({ reduxAsyncConnect }), window.__data)
// 3. Render `Router` with ReduxAsyncConnect middleware
hydrate((
<Provider store={store} key="provider">
<Router render={(props) => <ReduxAsyncConnect {...props}/>} history={browserHistory}>
<Route path="/" component={App}/>
</Router>
<BrowserRouter>
<ReduxAsyncConnect routes={routes} helpers={helpers} />
</BrowserRouter>
</Provider>

@@ -73,23 +96,33 @@ ), el)

import { renderToString } from 'react-dom/server'
import { match, RoutingContext } from 'react-router'
import StaticRouter from 'react-router/StaticRouter'
import { ReduxAsyncConnect, loadOnServer, reducer as reduxAsyncConnect } from 'redux-connect'
import createHistory from 'history/lib/createMemoryHistory';
import { Provider } from 'react-redux';
import { createStore, combineReducers } from 'redux';
import serialize from 'serialize-javascript';
import { parse as parseUrl } from 'url'
import { Provider } from 'react-redux'
import { createStore, combineReducers } from 'redux'
import serialize from 'serialize-javascript'
app.get('*', (req, res) => {
const store = createStore(combineReducers({ reduxAsyncConnect }));
const store = createStore(combineReducers({ reduxAsyncConnect }))
const url = req.originalUrl || req.url
const location = parseUrl(url)
match({ routes, location: req.url }, (err, redirect, renderProps) => {
// 1. load data
loadOnServer({ ...renderProps, store }).then(() => {
// 2. use `ReduxAsyncConnect` instead of `RoutingContext` and pass it `renderProps`
// 1. load data
loadOnServer({ store, location, routes, helpers })
.then(() => {
const context = {}
// 2. use `ReduxAsyncConnect` to render component tree
const appHTML = renderToString(
<Provider store={store} key="provider">
<ReduxAsyncConnect {...renderProps} />
<StaticRouter location={location} context={context}>
<ReduxAsyncConnect routes={routes} helpers={helpers} />
</StaticRouter>
</Provider>
)
// handle redirects
if (context.url) {
req.header('Location', context.url)
return res.send(302)
}

@@ -100,3 +133,2 @@ // 3. render the Redux initial data into the server markup

})
})
})

@@ -112,3 +144,5 @@

<!-- its a Redux initial data -->
<script dangerouslySetInnerHTML={{__html: `window.__data=${serialize(store.getState())};`}} charSet="UTF-8"/>
<script type="text/javascript">
window.__data=${serialize(store.getState())};
</script>
</body>

@@ -122,37 +156,2 @@ </html>

## Usage with `applyRouterMiddleware`
Thanks to @mmahalwy for a good usage example
Pass custom `render` method to `ReduxAsyncConnect`, it can look like this:
```js
// on client
const component = (
<Router
render={(props) => (
<ReduxAsyncConnect
{...props}
helpers={{ client }}
filter={item => !item.deferred}
render={applyRouterMiddleware(useScroll())}
/>
)}
history={history}
routes={getRoutes(store)}
/>
);
```
Basically what you do is instead of using render method like:
```js
const render = props => <RouterContext {...props} />;
```
you use
```js
const render = applyRouterMiddleware(...middleware);
```
## Usage with `ImmutableJS`

@@ -176,28 +175,2 @@

**React Router Issue**
While using the above immutablejs solution, an issue arose causing infinite recursion after firing
off a react standard action. The recursion was caused because the `componentWillReceiveProps` method will attempt to resync with the server. Thus `componentWillReceiveProps -> resync with server -> changes props via reducer -> componentWillReceiveProps`
The solution was to only resync with server on route changes. A `reloadOnPropsChange` prop is expose on the ReduxAsyncConnect component to allow customization of when a resync to the server should occur.
Method signature `(props, nextProps) => bool`
```js
const reloadOnPropsChange = (props, nextProps) => {
// reload only when path/route has changed
return props.location.pathname !== nextProps.location.pathname;
};
export const Root = ({ store, history }) => (
<Provider store={store} key="provider">
<Router render={(props) => <ReduxAsyncConnect {...props}
reloadOnPropsChange={reloadOnPropsChange}/>} history={history}>
{getRoutes(store)}
</Router>
</Provider>
);
```
## Comparing with other libraries

@@ -204,0 +177,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc