Improving API for connecting components
See original GitHub issueI’ve been using React-Redux for a while now, and I feel like there’s room to improve the connect() API. Currently the process for connecting a React component looks like this:
import { connect } from 'react-redux'
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{todos.map(todo => (
<Todo key={todo.id} {...todo} onClick={() => onTodoClick(todo.id)} />
))}
</ul>
)
const mapStateToProps = state => {
return {
todos: state.todos
}
}
const mapDispatchToProps = dispatch => {
return {
onTodoClick: id => {
dispatch(toggleTodo(id))
}
}
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
Defining several different functions and then using them to “connect” the component feels messier than it needs to be. One possible alternative could be to use something more like this:
class TodoList extends Redux.Component {
constructor(props) {
super(props, {
stateToProps: state => {
return { todos: state.todos }
},
dispatchToProps: dispatch => {
return {
onTodoClick: id => {
dispatch(toggleTodo(id))
}
}
})
}
render() {
return (
<ul>
{todos.map(todo => (
<Todo key={todo.id} {...todo} onClick={() => onTodoClick(todo.id)} />
))}
</ul>
)
}
}
Where Redux.Component would essentially act as a wrapper around React.Component. This alternative would keep the mappings contained within the relevant component, and would help prevent the creation of excess components. This approach in particular does require a class component instead of functional components, but I’d argue that’s an okay requirement, which follows the same mental model where only class components have access to local state.
I’m not saying the proposed change is the best option, I’m just hoping that we can have a good discussion about this.
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
I disagree with that being messy. You can use inline, anonymous functions if you don’t want to create something separate. But this is just basic functional design. That’s how JS works.
Also, extending React.Component is a bad idea. You immediately run into the issues of multiple inheritance. What if you want a component that is both a Redux component and another library’s component? Higher-order Components let you wrap things in a functional way, using the language rather than fighting against it.
It’s just a general gut feeling that I get when using Redux. It seems like there are so many different parts – actions, reducers, presentation components, container components, side effects, etc. that it makes it hard to internalize into one simple description.
As an example, consider React on it’s own. You could describe the general organization of a React app in a single sentence: “A single parent component is created, which creates child components, which then create their own child components, and so on.” And I know that if I step out of a React codebase for even several months, I’ll be able to come back and get re-situated relatively quickly. With Redux, I’m not able to describe the organization in a single sentence, and I feel disoriented whenever I return to a Redux codebase after some time away.
All of this might simply be due to a lack of experience with Redux, or due to how I’ve been organizing my applications. Thanks for linking those posts – I expect they will help clarify a few things for me!