1.0.1 • Published 4 years ago

prsh v1.0.1

Weekly downloads
3
License
MIT
Repository
github
Last release
4 years ago

Preact Redux Simple Hooks

Preact Redux Simple Hooks (prsh) is a tiny implementation of a set of Preact Hooks for interacting with a Redux store. In the spirit of Preact, it aims to be small and fast, weighing in at only 219 bytes minified and gzipped (95% smaller than react-redux).

Example

import { createElement } from 'preact';
import { createStore } from 'redux';
import { StoreContext, useSelector, useStore } from 'prsh';

function counter( state = 0, action ) {
	switch ( action.type ) {
		case 'INCREMENT':
			return state + 1;
	}

	return state;
}

const store = createStore( counter );

function CurrentCount() {
	const count = useSelector( ( state ) => state );

	return <div>Current value: { count }</div>;
}

function IncrementButton() {
	const { dispatch } = useStore();

	return (
		<button
			type="button"
			onClick={ () => dispatch( { type: 'INCREMENT' } ) }
		>
			Increment
		</button>
	);
}

function AppRoot() {
	return (
		<StoreContext.Provider value={ store }>
			<CurrentCount />
			<IncrementButton />
		</StoreContext.Provider>
	);
}

render( <AppRoot />, document.body );

CodePen: https://codepen.io/aduth/pen/QWbrLWe

Installation

Using npm:

npm install prsh

Or, download a pre-built copy from unpkg:

https://unpkg.com/prsh/dist/prsh.min.js

Or, start using in your browser without any download or build tools:

<script type="module">
import { StoreContext, useSelector } from 'https://unpkg.com/prsh?module';
// ...
</script>

API

StoreContext

The context object which passes a Redux store instance through a component tree.

A StoreContext.Provider should be rendered at the top-level of your application:

function AppRoot() {
	return (
		<StoreContext.Provider value={ store }>
			<Content />
		</StoreContext.Provider>
	);
}

You can also use this in combination with the useContext hook to get direct access to the store.

function ExampleComponent() {
	const store = useContext( StoreContext );

	// ...
}

useSelector

A hook which, given a selector function, returns a value from state. The hook creates a subscription to the store and ensures that your component is rerendered whenever the value changes.

function DoneTasks() {
	const todos = useSelector( ( state ) => state.todos );
	const doneTasks = todos.filter( ( todo ) => todo.done );

	return <ul>{ doneTasks.map( ( task ) => <li>{ task.text }</li> ) }</ul>;
}

useSelector uses strict equality === to determine whether the component should update. Because of this, you should be careful to note:

  • It is fine for a component to have multiple useSelector hooks in the same component. Avoid picking multiple parts of state into a single object or array return value, since an object or array will always be strictly unequal to the previous object or array ({} !== {}).
  • You should ensure that your selector returns a stable value, ideally a direct reference to a state path. Deriving state using operations like Array#filter should be done separate from the selector result, since filter will always produce a new array value and could cause your component to update more frequently than is necessary. If you need to memoize an expensive derivation, you can consider to use useMemo separate from your selector result.

useStore

A hook which returns access to the store of the current context, most commonly to dispatch to the store:

function IncrementButton() {
	const { dispatch } = useStore();

	return (
		<button
			type="button"
			onClick={ () => dispatch( { type: 'INCREMENT' } ) }
		>
			Increment
		</button>
	);
}

This is simply a shorthand of useContext( StoreContext );.

License

Copyright 2020 Andrew Duthie

Released under the MIT License.