Let's say we have the old traditional way of React / Redux: (you don't need to expand the code if you are familiar with it:)
import React from 'react';
import { connect } from 'react-redux';
function Count(props) {
return (
<div>
<button onClick={props.increment}> + </button>
{props.count}
<button onClick={props.decrement}> - </button>
</div>
);
}
const mapStateToProps = state => ({
count: state.count
});
const mapDispatchToProps = dispatch => ({
increment: () => dispatch({ type: 'INCREMENT' }),
decrement: () => dispatch({ type: 'DECREMENT' })
});
export default connect(mapStateToProps, mapDispatchToProps)(Count);
Now, using React Hooks useSelector()
and useDispatch()
, the above code could be written as this way:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
function Count() {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
const increment = () => dispatch({ type: 'INCREMENT' });
const decrement = () => dispatch({ type: 'DECREMENT' });
return (
<div>
<button onClick={increment}> + </button>
{count}
<button onClick={decrement}> - </button>
</div>
);
}
export default Count;
Both versions work exactly the same, by themselves, except, isn't version 1 highly reusable for Count
? That's because using a different mapStateToProps()
and mapDispatchToProps()
, we can use connect()
again to create another CountNoodle()
and now we have reused Count()
.
For version 2, Count()
is hard-wired with what state and dispatch it uses, so the whole Count()
is entirely not-reusable. That is, it has to be used with that particular state and particular dispatch, but nothing else. Isn't it true? So is version 2 above not recommended and actually you would have a version 3, which is not to call it Count()
but called it CountNoodle()
and "wire up" the state and dispatch, and re-use Count()
, which would be simply "presentational"?
So it may look something like this:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
// Count() actually would be in a different file and CountNoodle.js
// would import that file
function Count({count, increment, decrement}) {
return (
<div>
<button onClick={increment}> + </button>
{count}
<button onClick={decrement}> - </button>
</div>
);
}
function CountNoodle() {
const count = useSelector(state => state.countNoodle);
const dispatch = useDispatch();
const increment = () => dispatch({ type: 'INCREMENT_NOODLE' });
const decrement = () => dispatch({ type: 'DECREMENT_NOODLE' });
return <Count ...{count, increment, decrement} />;
// or return Count({count, increment, decrement});
}
export default CountNoodle;