// connect() is a function that injects Redux-related props into your component. | |
// You can inject data and callbacks that change that data by dispatching actions. | |
function connect(mapStateToProps, mapDispatchToProps) { | |
// It lets us inject component as the last step so people can use it as a decorator. | |
// Generally you don't need to worry about it. | |
return function (WrappedComponent) { | |
// It returns a component | |
return class extends React.Component { | |
render() { | |
return ( | |
// that renders your component | |
<WrappedComponent | |
{/* with its props */} | |
{...this.props} | |
{/* and additional props calculated from Redux store */} | |
{...mapStateToProps(store.getState(), this.props)} | |
{...mapDispatchToProps(store.dispatch, this.props)} | |
/> | |
) | |
} | |
componentDidMount() { | |
// it remembers to subscribe to the store so it doesn't miss updates | |
this.unsubscribe = store.subscribe(this.handleChange.bind(this)) | |
} | |
componentWillUnmount() { | |
// and unsubscribe later | |
this.unsubscribe() | |
} | |
handleChange() { | |
// and whenever the store state changes, it re-renders. | |
this.forceUpdate() | |
} | |
} | |
} | |
} | |
// This is not the real implementation but a mental model. | |
// It skips the question of where we get the "store" from (answer: <Provider> puts it in React context) | |
// and it skips any performance optimizations (real connect() makes sure we don't re-render in vain). | |
// The purpose of connect() is that you don't have to think about | |
// subscribing to the store or perf optimizations yourself, and | |
// instead you can specify how to get props based on Redux store state: | |
const ConnectedCounter = connect( | |
// Given Redux state, return props | |
state => ({ | |
value: state.counter, | |
}), | |
// Given Redux dispatch, return callback props | |
dispatch => ({ | |
onIncrement() { | |
dispatch({ type: 'INCREMENT' }) | |
} | |
}) | |
)(Counter) |
This comment has been minimized.
This comment has been minimized.
Thanks for the explanation, @gaearon! Might it be possible that you talk a bit about the performance optimizations in the connect function? Thanks! |
This comment has been minimized.
This comment has been minimized.
Really useful example. Thanks so much. Why is the unsubscribe method of the decorated component being called here in componentDidMount?
|
This comment has been minimized.
This comment has been minimized.
@therewillbecode see http://redux.js.org/docs/api/Store.html#subscribe
|
This comment has been minimized.
This comment has been minimized.
Super clear and helpful. Thanks :) |
This comment has been minimized.
This comment has been minimized.
Thank you! Pseudo-implementations help my mental model tons. |
This comment has been minimized.
This comment has been minimized.
Thanks a lot, it makes understanding the redux implementation much easier |
This comment has been minimized.
This comment has been minimized.
great explanation!!! thanks!!! |
This comment has been minimized.
This comment has been minimized.
Wow this is great |
This comment has been minimized.
This comment has been minimized.
Aha moment ! Concise and powerful : terms we hardly associate together with libraries. |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
here is my decorator to simplify things: import React from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import * as actions from "./actions";
const decorator = ComponentToDecorate => {
class ComponentDecorated extends React.Component {
render() {
const { authState, authActions, ...rest } = this.props;
return (
<ComponentToDecorate auth={{ state: authState, actions: authActions }}
{...rest}
/>
);
}
}
return connect(
state => ({
authState: state.services.auth.authentication
}),
dispatch => ({
authActions: bindActionCreators(actions, dispatch)
})
)(ComponentDecorated);
};
export default decorator; i use it in some complicated components. is there is anything wrong with this? |
This comment has been minimized.
This comment has been minimized.
fantastic! clear and concise, thanks @gaearon |
This comment has been minimized.
This comment has been minimized.
Thank you,very clear explanation,like you methods to educate. |
This comment has been minimized.
This comment has been minimized.
Good and brief explanation |
This comment has been minimized.
This comment has been minimized.
Fantastic work! |
This comment has been minimized.
This comment has been minimized.
Can this be used in prod? |
This comment has been minimized.
This comment has been minimized.
Hooks? |
This comment has been minimized.
This comment has been minimized.
So connect actually returns a new component hah !!! thanks for this snippet |
This comment has been minimized.
This comment has been minimized.
If I use this syntax.
|
This comment has been minimized.
This comment has been minimized.
Great Explanation! |
This comment has been minimized.
This comment has been minimized.
This helped. Thank you! |
This comment has been minimized.
This comment has been minimized.
Is it accurate to say that |
This comment has been minimized.
This comment has been minimized.
@ezmiller i would say - |
This comment has been minimized.
This comment has been minimized.
I just came here to see how a HOC works in practical. Thanks for this explaination. |
This comment has been minimized.
This comment has been minimized.
@gaearon don't you think the subscription logic should be in the |
This comment has been minimized.
This comment has been minimized.
Very clear explanation! |
This comment has been minimized.
This comment has been minimized.
Thank You That was a clear explanation !! |
This comment has been minimized.
This comment has been minimized.
Thanks, this mental model helping me a lot while learning react with redux :) |
This comment has been minimized.
This comment has been minimized.
@gaearon when connecting a component and using redux-thunk, dispatching twice would update the state twice. Would that mean that connected components would re-render twice (considering that the changes in state are something that would cause a re-render if used with component's native state)? |
This comment has been minimized.
Alright, now React next!😄