mapStateToProps
и mapDispatchToProps
— это функции, используемые в классическом подходе Redux для подключения React-компонентов к хранилищу (store) через функцию connect()
. Хотя современный подход с хуками (useSelector
и useDispatch
) более предпочтителен, понимание этих концепций важно для работы с legacy-кодом.
Назначение: Выбирает необходимые части состояния из Redux-хранилища и передает их в компонент как пропсы.
const mapStateToProps = (state, ownProps) => {
return {
// Выбираем нужные данные из store
counter: state.counter,
// Можем использовать ownProps для вычислений
doubleCounter: state.counter * 2,
// Фильтрация по пропсу компонента
todo: state.todos.find(todo => todo.id === ownProps.todoId)
};
};
Назначение: Предоставляет компоненту методы для отправки (dispatch) действий.
1. Как функция (полный контроль над dispatch):
const mapDispatchToProps = (dispatch, ownProps) => {
return {
increment: () => dispatch({ type: 'INCREMENT' }),
// С использованием action creators
addTodo: (text) => dispatch(addTodoAction(text)),
// С учетом ownProps
reset: () => dispatch({ type: 'RESET', id: ownProps.id })
};
};
2. Как объект (автоматическая обертка в dispatch):
const mapDispatchToProps = {
increment: () => ({ type: 'INCREMENT' }),
addTodo: addTodoAction // Автоматически будет dispatched
};
3. Пропустить (компонент получит только dispatch):
connect(mapStateToProps)(MyComponent);
// В компоненте: this.props.dispatch({ type: 'INCREMENT' })
import { connect } from 'react-redux';
import { increment, addTodo } from '../actions';
const MyComponent = ({ counter, increment, addTodo }) => (
<div>
<span>{counter}</span>
<button onClick={increment}>+</button>
<button onClick={() => addTodo('Learn Redux')}>Add Todo</button>
</div>
);
const mapStateToProps = state => ({
counter: state.counter
});
const mapDispatchToProps = {
increment,
addTodo
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(MyComponent);
Функция | Аналог с хуками |
---|---|
mapStateToProps | useSelector |
mapDispatchToProps | useDispatch + action creators |
Пример с хуками:
import { useSelector, useDispatch } from 'react-redux';
import { increment } from '../features/counter/counterSlice';
function Counter() {
const counter = useSelector(state => state.counter);
const dispatch = useDispatch();
return (
<div>
<span>{counter}</span>
<button onClick={() => dispatch(increment())}>+</button>
</div>
);
}
mapStateToProps:
mapDispatchToProps:
Основное отличие от хуков:
Когда использовать:
Современные React-приложения следует писать с использованием хуков useSelector
и useDispatch
, но понимание этих функций необходимо для поддержки старых кодовых баз.