I'm new to react & redux so I made a simple page to get familiar with its concepts.
I just got this problem, store.subscribe() doesn't fire after I clicked the button once. However, it fires after I clicked twice. The more weird thing is when I clicked the button again, the function was triggered more than once.
Btw I'm not asking to correct my code (I know it sucks). I'm just wondering why my code have the strange behavior.
Let me just show the code:
/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import store from './store';
import sendAction from './store/actionCreator'
class App extends React.Component {
render() {
return (
<div>
<button onClick={() => this.handleClick()}>Click me to send an action</button>
<p>{store.getState().value}</p>
</div>
);
}
handleClick = () => {
console.log('Before dispatch, the state is: ', store.getState());
store.dispatch(sendAction());
console.log('After dispatch, the state is: ', store.getState());
store.subscribe(() => {
console.log('subscribe triggered');
this.setState({})
});
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
I will give you the Chrome console outputs below.
First time I clicked the button: enter image description here
Second time I clicked the button: enter image description here
More clicks: enter image description here
For completeness, here's the rest of the code but I believe they have nothing to do with the problem.
/src/store/actionCreator.js
export const SEND_MESSAGE='SEND_MESSAGE';
export default function sendAction() {
return {
type: SEND_MESSAGE,
value: 'changed',
};
}
/src/store/reducer.js
import {SEND_MESSAGE} from './actionCreator';
const initialState={
value: 'default text',
};
export default (state=initialState, action) => {
switch (action.type) {
case SEND_MESSAGE: {
return Object.assign({}, state, action);
}
default: {
return state;
}
}
}
/src/store/index.js
import {createStore} from 'redux';
import reducer from './reducer';
const store=createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export default store;
You are adding a new store subscription each time the handleClick handler is invoked.
Establish the subscription once when the component mounts using the componentDidMount lifecycle method. Don't forget to unsubscribe from the store when the component unmounts.
class App extends React.Component {
unsubscribe = null;
componentDidMount() {
this.unsubscribe = store.subscribe(() => {
console.log('subscribe triggered');
this.setState({})
});
}
componentWillUnmount() {
this.unsubscribe();
}
handleClick = () => {
console.log('Before dispatch, the state is: ', store.getState());
store.dispatch(sendAction());
console.log('After dispatch, the state is: ', store.getState());
}
render() {
return (
<div>
<button onClick={() => this.handleClick()}>Click me to send an action</button>
<p>{store.getState().value}</p>
</div>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With