Допустим, у нас есть старый традиционный способ React / Redux: (вам не нужно расширять код, если вы знакомы с ним:)
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);
Теперь, используя React Hooks useSelector()
и useDispatch()
, приведенный выше код можно записать так:
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;
Обе версии работают одинаково сами по себе, за исключением того, что версия 1 не может использоваться повторно для Count
? Это потому, что используя разные mapStateToProps()
и mapDispatchToProps()
, мы можем снова использовать connect()
для создания другого CountNoodle()
, и теперь мы повторно использовали Count()
.
Для версии 2 Count()
сложно - с каким состоянием и диспетчеризацией он использует, поэтому весь Count()
не подлежит повторному использованию. То есть, должен использоваться с этим конкретным состоянием и конкретной отправкой, но больше ничего. Разве это не правда? Так что версия 2 выше не рекомендуется, и на самом деле у вас будет версия 3, которая не будет называть ее Count()
, а будет называть ее CountNoodle()
и "связывать" состояние и отправлять, и повторно использовать Count()
, что будет просто "презентационным"?
Так что это может выглядеть примерно так:
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;