Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
react-reducer-store
Advanced tools
Global state with React hooks and Context API
Demo app uses the live version of react-reducer-store. To run the Demo app.
cd demo
yarn start
Demo app is hosted in Github pages. Apart from normal functionality that you expect from the app, clicking the Random better should not output the message: "List component is rendering" in the console. View the console and check if the logs are acceptable to you. The only middleware that is of real use if the redux-logger middleware. The rest of the middleware don't add value in the new Hooks api.
Write as many reducers as you want in your React app. Combine all the reducers to a root reducer as follows.
import { combineReducers } from 'react-reducer-store';
import todoReducer from './todoReducer';
import randomReducer from './randomReducer';
export default combineReducers({
todo: todoReducer,
random: randomReducer
});
Wrap the root component of your project with Store component
import { Store } from 'react-reducer-store';
import rootReducer from './rootReducer';
export default function App() {
return (
<Store rootReducer={rootReducer}>
<Form />
<List />
</Store>
);
}
Use the useDispatch hook to get the dispatch function to root reducer.
import { useDispatch } from 'react-reducer-store';
export default function Form(props) {
const dispatch = useDispatch()
function handleRandom() {
dispatch({ type: 'DO_RANDOM' });
}
Use the store from the List component using useStore hook
import { useStore, useDispatch } from 'react-reducer-store';
export default function List() {
const todo = useStore(state => state.todo, []);
const dispatch = useDispatch();
function handleDelete(id) {
dispatch({
type: 'DELETE_TODO',
id
});
}
return (
<div className="list">
{todo.map(item => (
<ListItem key={item.id}
onDelete={handleDelete.bind(null, item.id)}
text={item.text}
/>
))}
</div>
);
}
To add logging to the console, set the log prop on the Store to true.
<Store rootReducer={rootReducer} log={true}>
...
</Store>
Output looks like below:
At first, I thought the useReducer is a great API, one which should have been part of React since the beginning. So, I started out creating a global store with just useReducer hook. I was hoping that calling useReducer with the same reducer function will give the same state. So, it was a great way of sharing state. But useReducer hook does not work that way. To more about useReducer hook, read my first blog post on this topic.
Then I thought of putting the global state in the Context. I was able to put the global state in context and use it everywhere using a useStore hook. I have outlined the approach in the second article on the same topic. There was a problem with this approach. There were too many updates happening when we put the global store in the context. All components subscribed to the store updated even when they don't need that data.
So, the official solution from React team is to put the dispatch function into the global context and pass the store down as props. I outlined this approach in the third article where I explain why Redux is required. At the time of writing the third article, I did not know the Redux team was struggling with the problem.
The problem of using subscription mechanism that I outlined in the third article to fix too many updates is that it does not work well with concurrent React. So, the only way to solve this problem is to pass the global store into the Context API. And figure out some way to cancel the update from happening. But there is no hook to cancel an update which is already kick-started by the useContext hook. So, the only way around this is to have a higher order component via the connect function to cancel the updates from the context. So, we are back to Square one where we have global store in Context object and a connect HOC to prevent too many updates. Currently, there is no way with the official React API to write a useStore hook. Till then, this is just an experimental project, definitely only for small apps and demo projects.
FAQs
Global state with React hooks and Context API
We found that react-reducer-store demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.