Как стать автором
Обновить

Комментарии 10

В новой версии react-redux эта проблема и другие похожие решается более элегантно через


connectAdvanced(selectorFactory, [connectOptions])

https://github.com/reactjs/react-redux/blob/next/docs/api.md#connectadvancedselectorfactory-connectoptions
Там можно более гибко конфигурировать props для вложенного компонента.


Пример кода:


import * as actionCreators from './actionCreators'
import { bindActionCreators } from 'redux'

function selectorFactory(dispatch) {
  let state = {}
  let ownProps = {}
  let result = {}
  const actions = bindActionCreators(actionCreators, dispatch)
  const addTodo = (text) => actions.addTodo(ownProps.userId, text)
  return (nextState, nextOwnProps) => {
    const todos = nextState.todos[nextProps.userId]
    const nextResult = { ...nextOwnProps, todos, addTodo }
    state = nextState
    ownProps = nextOwnProps
    if (!shallowEqual(result, nextResult)) result = nextResult
    return result
  }
}
export default connectAdvanced(selectorFactory)(TodoApp)

А я в таких случаях обычно передаю срез нужного мне состояния из компонента, что-то типа onClick={(myState) => this.props.togglePlay(myState)}. Или так делать – bad practice?

Bad practice, потому что тогда компонент должен знать о структуре стейта слишком много — больше, чем ему полагается для своей функциональности. То же касается и селекторов. В простых приложениях это может работать, но с ростом количества фич это становится все сложнее поддерживать (при изменении структуры state'а приходится вносить изменения в компоненты, селекторы и так далее).

Ну можно же передавать туда и просто свои props – тогда это ничем не будет отличаться от способа с mergeProps.

Я думал, что речь о том, что стейт разбирается внутри, скажем, togglePlay(). Если myState — это уже нужный компоненту кусок стейта — это неплохо. Однако bad practice тут в том, что ваш компонент вообще знает, что что-то хранится в каком-то там стейте, вы его передаете туда-cюда. В этом плане еще лучше, если компонент вообще не будет знать, откуда берутся props (из стейта, переданы вручную, и так далее), это позволяет его легко переиспользовать. А ко всему прочему это проще тестировать.

Ну можно же передавать туда и просто свои props
Куда «туда»? :)

Кстати, как у вас в примере 'myState' оказывается аргументом обработчика onClick? Там же SyntheticEvent.
В этом плане еще лучше, если компонент вообще не будет знать, откуда берутся props (из стейта, переданы вручную, и так далее)

Ну да, компонент знает только то, что мы ему передали в props. Но, соответственно, он может и передать в функцию-обработчик какую-то часть этих props.


Кстати, как у вас в примере 'myState' оказывается аргументом обработчика onClick? Там же SyntheticEvent.

Да, затупил, конечно же. Должно быть что-то такое:


onClick={(e) => this.props.togglePlay(this.props.play)}
А, в таком случае — вообще никаких нареканий, так можно и это, в общем-то, не bad practice. Тут скорее наоборот — иметь в props экшены с уже «прошитыми» props бывает просто удобно, чтобы каждый раз не прокидывать их внутри компонента. Я сам тоже предпочитаю эту логику убирать за его пределы, оставляя презентационному (presentational/dumb) компоненту минимум простора для принятия подобных решений.
По-моему, redux-thunk как-то всё-таки понятнее…
const toggle = () => {
    dispatch(togglePlay());
    ...


где объявлен togglePlay?
В actions, видимо.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории