New React Redux coding style with hooks without selectors

April 20, 2019 0 Comments

New React Redux coding style with hooks without selectors

 

 

React Redux is one of popular web tech stacks. As I found React hooks so promising, I have been developing a hooks-based library for React Redux called “reactive-react-redux.”

Coding style using this library is mentally different from the official react-redux. Thanks to Proxy, developers don’t need to care about optimization, but just focus on composition of logic.

This library provides two basic hooks: useReduxState and useReduxDispatch. This article shows example code how to use them.

We use a tiny example in this article. The following is how our Redux store state looks like.

const state = {
items: [
{ title: 'ttt1', description: 'ddd1' },
{ title: 'ttt2', description: 'ddd2' },
{ title: 'ttt3', description: 'ddd3' },
},
};

We can create a custom hook based on useReduxState. Let’s create a hook that receives an item index and returns an item object.

const useItem = (index) => {
const state = useReduxState();
return state.items[index];
};

Now, we use this hook to create a component.

const Item = ({ index }) => {
const item = useItem(index);
return (
<div>{item.title}{' - '}{item.description}</div>
);
};

This style is totally different from the one with connect, which would look like the following.

const Item = ({ item }) => (
<div>{item.title}{' - '}{item.description}</div>
);
const mapStateToProps = (state, ownProps) => ({
item: state.items[ownProps.index],
});
const ConnectedItem = connect(mapStateToProps)(Item);

Suppose our component only uses title and no description, our component would be something like this.

const ItemWithTitle = ({ index }) => {
const item = useItem(index);
return (
<div>{item.title}</div>
);
};

Because useReduxState tracks the usage of state in render, it won’t trigger re-render if only description is changed. We don’t need to create “useItemWithTitle” and “useItemWithTitleAndDescription” hooks, but just one “useItem” does the job.

This is an important aspect of the hook. We can even create “useItemTitle.”

const useItemTitle = (index) => {
const item = useItem(index);
return item.title;
};

Note that the examples above can be over-simplified and they don’t seem very useful, but hopefully they explain the idea.

There can be various patterns for useReduxDispatch.

Probably the simplest is to create a hook to dispatch a specific action.

const useAddItem = () => {
const dispatch = useReduxDispatch();
const addItem = title => dispatch({ type: 'ADD_ITEM', title });
return addItem;
};

If you already have an action creator, you can create a general hook.

const useAction = (actionCreator) => {
const dispatch = useReduxDispatch();
return (...args) => dispatch(actionCreator(...args));
};

You could also pass action creators, if you prefer.

const useActions = (actionCreators) => {
// ...
};

When I started writing this article, I was hoping to come up with better example code so that readers get aha. Reading the entire article again, I’m not very confident if this is appealing as expected. I decided to let go anyway, and will see. Comments would be appreciated by Twitter or GitHub issues.


Tag cloud