Reputation: 5647
This isn't a question about react-redux hooks like useSelector
or useDispatch
. I'm curious to know how old school react-redux connect()
with a functional component and when it's necessary to use React hooks like useEffect
in this example.
Suppose I have this functional component that renders a "Hello world" in green if someReduxData
is present, otherwise it render it in red.
const RandomComponent = ({ someReduxData }) => {
const style = {
color: someReduxData ? "green" : "red";
};
return (
<div style={style}>Hello world</div>
);
}
const mapStateToProps = (state) => {
return {
someReduxData: state.someReduxData;
};
};
export default connect(mapStateToProps)(RandomComponent);
Let's say when the component first mounts to the DOM, someReduxData
is null. Then it changes state so it's not null anymore. Will this force a re-render of RandomComponent
so it renders in green? If not, then I assume I will need to listen for changes on someReduxData
with useEffect()
?
Upvotes: 2
Views: 5917
Reputation: 11017
It will force a re-render of RandomComponent. connect works the same regardless of class vs function component.
Here's an example using a function component: There's a setTimeout of 2 seconds before an action dispatches that turns the App div green.
There's also an example of that same component using a hook instead of connect.
The main difference between connect and hooks are that connect essentially acts as React.memo for the component. This can be toggled off with a boolean flag, but you likely will never have to do that: https://react-redux.js.org/api/connect#pure-boolean
const initialstate = {
someReduxData: null,
};
const reducer = (state = initialstate, action) => {
switch (action.type) {
case 'action':
return {
someReduxData: action.data,
};
default:
return initialstate;
}
};
const actionCreator = (data) => {
return {
type: 'action',
data,
};
};
const store = Redux.createStore(reducer);
const App = ({ someReduxData }) => {
return (
<div className={someReduxData}>
Some div -- Will turn green in 2 seconds
</div>
);
};
const mapStateToProps = (state) => {
return {
someReduxData: state.someReduxData,
};
};
const WrappedApp = ReactRedux.connect(mapStateToProps)(App);
const AppWithHooks = () => {
const someReduxData = ReactRedux.useSelector(state=>state.someReduxData);
return (
<div className={someReduxData}>
Some div with a hook -- Will turn green in 2 seconds
</div>
);
};
ReactDOM.render(
<ReactRedux.Provider store={store}>
<WrappedApp />
<AppWithHooks />
</ReactRedux.Provider>,
document.querySelector('#root')
);
setTimeout(() => store.dispatch(actionCreator('green')), 2000);
.green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js" integrity="sha256-7nQo8jg3+LLQfXy/aqP5D6XtqDQRODTO18xBdHhQow4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js" integrity="sha256-JuJho1zqwIX4ytqII+qIgEoCrGDVSaM3+Ul7AtHv2zY=" crossorigin="anonymous"></script>
<div id="root" />
Upvotes: 2