react-redux-partial
TypeScript icon, indicating that this package has built-in type declarations

0.2.0 • Public • Published

react-redux-partial

npm version

This library is a wrapper of the original react-redux library and use it inside. react-redux-partial has beed created for 2 reasons:

  • improve performance of an application when large amount of connected components are used
  • write connected react-components which are independent of a shape of redux store

Performance improvement

Consider, you have a redux store of this interface:

interface PageState {
	loginForm: LoginFormType;
	items: SomeItemsType;
}

And you have a few dozens of components connected to the items field of the store. Then each action which changes loginForm will cause call of all selectors of components connected to theitems. It can be slowly.

Using react-redux-partial you can easy connect components to the items field such way the corresponding selectors are called when only the items fields is changed.

Independent connected components

Using react-redux-partial you can create a connected to a store component which can work with a state of some interface. For example:

interface LoginFormType {
	login: string;
	password: string;
}

And then you can reuse this component on any page where a redux state has the login form data in any field.

API

createConnects

createConnects function returns a set of methods to connect component to a part of a redux store.

import { createConnects } from 'react-redux-partial';

type LoginFormType = {
	login: string;
	password: string;
};

const { connect } = createConnects<LofinFormType>();

createConnects returns an object with fields:

  • context
  • useDispatch
  • useSelector
  • useStore
  • connect
  • Provider
  • withProvider

context

createConnects returns a new context object. It can be use directly or as a parameter of original Provider and connect from react-redux. All other methods returned by createConnects work only with this context.

useDispatch, useSelector, useStore, connect

These functions work as original useDispatch, useSelector, useStore, connect functions from react-redux but only with a context returned by the same createConnects call.

Provider

The Provider component adds a store to react context. To get the store from context you can use the context returned by createConnects or any of methods useDispatch, useSelector, useStore, connect.

Pass a store

You can use Provider as you usually use the react-redux provider.

import { render } from 'react';
import { createConnects } from 'react-redux-partial';
import { createStore } from 'redux';
import SomeComponent from './SomeComponent';

type LoginFormType = {
	login: string;
	password: string;
};

const store = createStore(/* arguments */);

const { Provider, connect } = createConnects<LofinFormType>();

const ConnectedComponent = connect(/* arguments */)(SomeComponent);

render(
	<Provider store={store}>
		<ConnectedComponent />
	</Provider>,
	element
);
Pass a parent context

Also you can create some ConnectedComponent and use it with stores which contain a state of different types.

Component.tsx

export type LoginFormType = {
	login: string;
	password: string;
};

const { Provider, connect } = createConnects<LofinFormType>();

export const ConnectedComponent = connect(/* arguments */)(SomeComponent);
export { Provider };

You can pass to the Provider a parent context and a field where is a state of type LoginFormType.

import { render } from 'react';
import { createConnects } from 'react-redux-partial';
import { createStore } from 'redux';
import ConnectedComponent, {
	LoginFormType,
	Provider as ConnectedComponentProvider,
} from './Component';

type PageStateLoginFormType = {
	loginForm: LoginFormType;
};

const store = createStore(/* arguments */);

const { Provider, context } = createConnects<PageStateLoginFormType>();

render(
	<Provider store={store}>
		<ConnectedComponentProvider context={context} fields="loginForm">
			<ConnectedComponent />
		</ConnectedComponentProvider>
	</Provider>,
	element
);

Selectors which are passed to connect will be invoked only if the loginForm field is changed. This can improve a page performance.

Also you can pass a select props if you want to transform parent state to chils state. For example:

import ConnectedComponent, {
	LoginFormType,
	Provider as ConnectedComponentProvider,
} from './Component';

type PageStateLoginFormType = {
	loginForm: {
		email: string;
		pass: string;
	};
	/** some other fields */
};

function selector(state: { email: string; pass: string }): LoginFormType {
	return {
		login: state.email,
		password: state.pass,
	};
}

render(
	<Provider store={store}>
		<ConnectedComponentProvider
			context={context}
			fields="loginForm"
			select={selector}
		>
			<ConnectedComponent />
		</ConnectedComponentProvider>
	</Provider>,
	element
);

Or you can pass an object instead of a string to fields prop.

import ConnectedComponent, {
	LoginFormType,
	Provider as ConnectedComponentProvider,
} from './Component';

type PageStateLoginFormType = {
	user: {
		email: string;
		phone: string;
	};
	pass: string;
	orders: any[];
};

function selector(state: {
	user: {
		email: string;
	};
	pass: string;
}): LoginFormType {
	return {
		login: state.user.email,
		password: state.pass,
	};
}

render(
	<Provider store={store}>
		<ConnectedComponentProvider
			context={context}
			fields={{
				user: { email: true },
				pass: true,
			}}
			select={selector}
		>
			<ConnectedComponent />
		</ConnectedComponentProvider>
	</Provider>,
	element
);

For each prop you want to pass to a child provider you should specify true. Also you can use select prop to transform parent state.

Use custom partial provider instead of original

I some cases you may have to use a original react-redux provider in a page root. If you have some components which are connected with methods returned by createConnects, then you should use a Provider component from react-redux-partial instead of original. It has the same behavior but turns on performance optimization.

Override original react-redux context

If you want to use some component connected by original connect you can you use OverrideStoreProvider to connect it to a partial store. It can improve performance.

With partial root provider.

import { createConnects, OverrideStoreProvider } from 'react-redux-partial';

const { Provider, context } = createConnects();
const store = createStore();

<Provider store={store}>
	...
	<OverrideStoreProvider context={context} fields="someField">
		<ConnectedComponent />
	</OverrideStoreProvider>
	...
</Provider>;

With original root provider.

import { Provider } from 'react-redux';
import { OverrideStoreProvider } from 'react-redux-partial';

const store = createStore();

<Provider store={store}>
	...
	<OverrideStoreProvider fields="someField">
		<ConnectedComponent />
	</OverrideStoreProvider>
	...
</Provider>;

Package Sidebar

Install

npm i react-redux-partial

Weekly Downloads

1

Version

0.2.0

License

MIT

Unpacked Size

28 kB

Total Files

7

Last publish

Collaborators

  • megazazik