How to set react state with new props immediately after calling `dispatch` via react-redux connect?












1














I'm new to React and Redux and I'm trying to build a website. I'm using Material-UI components. The AppSearchBarInput is an input in the header where users can search for an id (referred to as appId in the code). If appId is found in the database then I want to redirect to another page (this.props.history.push('/app/appInfo');). If the input is blank then I display a snackbar (AppNotFound) with warning message as well as when the input doesn't exist in the database.



In the onKeyDown method I use connect to dispatch an action which checks if the id exists in the database (dispatch is called from getAppInfo using redux-thunk). Then I need to immediately get the new Redux state via props in order to decide whether the id was found or not and depending on this I set snackBarOpen local state property to true or false.



The problem is that I can't get the updated props within the same method when calling dispatch. I could use componentDidUpdate but then I can't update local store from it. Is there some workaround for this situation either using some react lifecycle method or redux trick?



import React, { Component } from 'react';
import PropTypes from 'prop-types';
import InputBase from '@material-ui/core/InputBase';
import { withStyles } from '@material-ui/core/styles';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { getAppInfo } from '../../actions/appActions.js';
import constants from '../../constants.js';

import { AppSearchBarInputStyles } from '../styles/Material-UI/muiStyles.js';
import AppNotFound from './AppNotFound.js';

import * as log from 'loglevel';
log.setLevel("debug")


class AppSearchBarInput extends Component {
state = {
appId: '',
snackBarOpen: false
}

onChange = e => {
this.setState({ appId: e.target.value });
}

onKeyDown = e => {
const { appId } = this.state;

if (e.keyCode === constants.ENTER_KEY) {
if (appId.trim() !== '') {
this.props.getAppInfo({ appId });
this.setState({
appId: ''
});

const { found } = this.props.app; // ! problem here !
if (found) {
this.props.history.push('/app/appInfo');
} else {
this.setState({
snackBarOpen: true
});
}
} else {
this.setState({
snackBarOpen: true
});
}
}
}

handleCloseSnackBar = () => {
this.setState({
snackBarOpen: false
});
}

render() {

const { classes } = this.props;
const { appId, snackBarOpen } = this.state;
const { found } = this.props.app;
let message = '';
if (!found) {
message = appId === '' ? constants.MESSAGES.APP_BLANK() : constants.MESSAGES.APP_NOT_FOUND(appId);
}

return (
<div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
value={this.state.appId} />
<AppNotFound message={message}
open={snackBarOpen && !found}
onClose={this.handleCloseSnackBar}/>
</div>
)
}
}

AppSearchBarInput.propTypes = {
classes: PropTypes.object.isRequired
}

const mapStateToProps = state => ({
app: state.app.app
});

const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);









share|improve this question
























  • There's no dispatch in the code you posted. Please, update it to clarify where it should be. I could use componentDidUpdate but then I can't update local store from it - why?
    – estus
    Nov 20 at 22:08












  • Using componentWillReceiveProps solved my problem but it's still not the recommended method to use, though.
    – hitchhiker
    Nov 21 at 21:05
















1














I'm new to React and Redux and I'm trying to build a website. I'm using Material-UI components. The AppSearchBarInput is an input in the header where users can search for an id (referred to as appId in the code). If appId is found in the database then I want to redirect to another page (this.props.history.push('/app/appInfo');). If the input is blank then I display a snackbar (AppNotFound) with warning message as well as when the input doesn't exist in the database.



In the onKeyDown method I use connect to dispatch an action which checks if the id exists in the database (dispatch is called from getAppInfo using redux-thunk). Then I need to immediately get the new Redux state via props in order to decide whether the id was found or not and depending on this I set snackBarOpen local state property to true or false.



The problem is that I can't get the updated props within the same method when calling dispatch. I could use componentDidUpdate but then I can't update local store from it. Is there some workaround for this situation either using some react lifecycle method or redux trick?



import React, { Component } from 'react';
import PropTypes from 'prop-types';
import InputBase from '@material-ui/core/InputBase';
import { withStyles } from '@material-ui/core/styles';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { getAppInfo } from '../../actions/appActions.js';
import constants from '../../constants.js';

import { AppSearchBarInputStyles } from '../styles/Material-UI/muiStyles.js';
import AppNotFound from './AppNotFound.js';

import * as log from 'loglevel';
log.setLevel("debug")


class AppSearchBarInput extends Component {
state = {
appId: '',
snackBarOpen: false
}

onChange = e => {
this.setState({ appId: e.target.value });
}

onKeyDown = e => {
const { appId } = this.state;

if (e.keyCode === constants.ENTER_KEY) {
if (appId.trim() !== '') {
this.props.getAppInfo({ appId });
this.setState({
appId: ''
});

const { found } = this.props.app; // ! problem here !
if (found) {
this.props.history.push('/app/appInfo');
} else {
this.setState({
snackBarOpen: true
});
}
} else {
this.setState({
snackBarOpen: true
});
}
}
}

handleCloseSnackBar = () => {
this.setState({
snackBarOpen: false
});
}

render() {

const { classes } = this.props;
const { appId, snackBarOpen } = this.state;
const { found } = this.props.app;
let message = '';
if (!found) {
message = appId === '' ? constants.MESSAGES.APP_BLANK() : constants.MESSAGES.APP_NOT_FOUND(appId);
}

return (
<div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
value={this.state.appId} />
<AppNotFound message={message}
open={snackBarOpen && !found}
onClose={this.handleCloseSnackBar}/>
</div>
)
}
}

AppSearchBarInput.propTypes = {
classes: PropTypes.object.isRequired
}

const mapStateToProps = state => ({
app: state.app.app
});

const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);









share|improve this question
























  • There's no dispatch in the code you posted. Please, update it to clarify where it should be. I could use componentDidUpdate but then I can't update local store from it - why?
    – estus
    Nov 20 at 22:08












  • Using componentWillReceiveProps solved my problem but it's still not the recommended method to use, though.
    – hitchhiker
    Nov 21 at 21:05














1












1








1







I'm new to React and Redux and I'm trying to build a website. I'm using Material-UI components. The AppSearchBarInput is an input in the header where users can search for an id (referred to as appId in the code). If appId is found in the database then I want to redirect to another page (this.props.history.push('/app/appInfo');). If the input is blank then I display a snackbar (AppNotFound) with warning message as well as when the input doesn't exist in the database.



In the onKeyDown method I use connect to dispatch an action which checks if the id exists in the database (dispatch is called from getAppInfo using redux-thunk). Then I need to immediately get the new Redux state via props in order to decide whether the id was found or not and depending on this I set snackBarOpen local state property to true or false.



The problem is that I can't get the updated props within the same method when calling dispatch. I could use componentDidUpdate but then I can't update local store from it. Is there some workaround for this situation either using some react lifecycle method or redux trick?



import React, { Component } from 'react';
import PropTypes from 'prop-types';
import InputBase from '@material-ui/core/InputBase';
import { withStyles } from '@material-ui/core/styles';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { getAppInfo } from '../../actions/appActions.js';
import constants from '../../constants.js';

import { AppSearchBarInputStyles } from '../styles/Material-UI/muiStyles.js';
import AppNotFound from './AppNotFound.js';

import * as log from 'loglevel';
log.setLevel("debug")


class AppSearchBarInput extends Component {
state = {
appId: '',
snackBarOpen: false
}

onChange = e => {
this.setState({ appId: e.target.value });
}

onKeyDown = e => {
const { appId } = this.state;

if (e.keyCode === constants.ENTER_KEY) {
if (appId.trim() !== '') {
this.props.getAppInfo({ appId });
this.setState({
appId: ''
});

const { found } = this.props.app; // ! problem here !
if (found) {
this.props.history.push('/app/appInfo');
} else {
this.setState({
snackBarOpen: true
});
}
} else {
this.setState({
snackBarOpen: true
});
}
}
}

handleCloseSnackBar = () => {
this.setState({
snackBarOpen: false
});
}

render() {

const { classes } = this.props;
const { appId, snackBarOpen } = this.state;
const { found } = this.props.app;
let message = '';
if (!found) {
message = appId === '' ? constants.MESSAGES.APP_BLANK() : constants.MESSAGES.APP_NOT_FOUND(appId);
}

return (
<div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
value={this.state.appId} />
<AppNotFound message={message}
open={snackBarOpen && !found}
onClose={this.handleCloseSnackBar}/>
</div>
)
}
}

AppSearchBarInput.propTypes = {
classes: PropTypes.object.isRequired
}

const mapStateToProps = state => ({
app: state.app.app
});

const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);









share|improve this question















I'm new to React and Redux and I'm trying to build a website. I'm using Material-UI components. The AppSearchBarInput is an input in the header where users can search for an id (referred to as appId in the code). If appId is found in the database then I want to redirect to another page (this.props.history.push('/app/appInfo');). If the input is blank then I display a snackbar (AppNotFound) with warning message as well as when the input doesn't exist in the database.



In the onKeyDown method I use connect to dispatch an action which checks if the id exists in the database (dispatch is called from getAppInfo using redux-thunk). Then I need to immediately get the new Redux state via props in order to decide whether the id was found or not and depending on this I set snackBarOpen local state property to true or false.



The problem is that I can't get the updated props within the same method when calling dispatch. I could use componentDidUpdate but then I can't update local store from it. Is there some workaround for this situation either using some react lifecycle method or redux trick?



import React, { Component } from 'react';
import PropTypes from 'prop-types';
import InputBase from '@material-ui/core/InputBase';
import { withStyles } from '@material-ui/core/styles';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { getAppInfo } from '../../actions/appActions.js';
import constants from '../../constants.js';

import { AppSearchBarInputStyles } from '../styles/Material-UI/muiStyles.js';
import AppNotFound from './AppNotFound.js';

import * as log from 'loglevel';
log.setLevel("debug")


class AppSearchBarInput extends Component {
state = {
appId: '',
snackBarOpen: false
}

onChange = e => {
this.setState({ appId: e.target.value });
}

onKeyDown = e => {
const { appId } = this.state;

if (e.keyCode === constants.ENTER_KEY) {
if (appId.trim() !== '') {
this.props.getAppInfo({ appId });
this.setState({
appId: ''
});

const { found } = this.props.app; // ! problem here !
if (found) {
this.props.history.push('/app/appInfo');
} else {
this.setState({
snackBarOpen: true
});
}
} else {
this.setState({
snackBarOpen: true
});
}
}
}

handleCloseSnackBar = () => {
this.setState({
snackBarOpen: false
});
}

render() {

const { classes } = this.props;
const { appId, snackBarOpen } = this.state;
const { found } = this.props.app;
let message = '';
if (!found) {
message = appId === '' ? constants.MESSAGES.APP_BLANK() : constants.MESSAGES.APP_NOT_FOUND(appId);
}

return (
<div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
value={this.state.appId} />
<AppNotFound message={message}
open={snackBarOpen && !found}
onClose={this.handleCloseSnackBar}/>
</div>
)
}
}

AppSearchBarInput.propTypes = {
classes: PropTypes.object.isRequired
}

const mapStateToProps = state => ({
app: state.app.app
});

const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);






javascript reactjs redux react-redux






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 at 5:19

























asked Nov 20 at 21:18









hitchhiker

727




727












  • There's no dispatch in the code you posted. Please, update it to clarify where it should be. I could use componentDidUpdate but then I can't update local store from it - why?
    – estus
    Nov 20 at 22:08












  • Using componentWillReceiveProps solved my problem but it's still not the recommended method to use, though.
    – hitchhiker
    Nov 21 at 21:05


















  • There's no dispatch in the code you posted. Please, update it to clarify where it should be. I could use componentDidUpdate but then I can't update local store from it - why?
    – estus
    Nov 20 at 22:08












  • Using componentWillReceiveProps solved my problem but it's still not the recommended method to use, though.
    – hitchhiker
    Nov 21 at 21:05
















There's no dispatch in the code you posted. Please, update it to clarify where it should be. I could use componentDidUpdate but then I can't update local store from it - why?
– estus
Nov 20 at 22:08






There's no dispatch in the code you posted. Please, update it to clarify where it should be. I could use componentDidUpdate but then I can't update local store from it - why?
– estus
Nov 20 at 22:08














Using componentWillReceiveProps solved my problem but it's still not the recommended method to use, though.
– hitchhiker
Nov 21 at 21:05




Using componentWillReceiveProps solved my problem but it's still not the recommended method to use, though.
– hitchhiker
Nov 21 at 21:05












1 Answer
1






active

oldest

votes


















0














From the look of your code you have no dispatch method. If data was really fetched, then you're not getting updates because withRouter actually blocks shouldComponentUpdate. If you want updated state, wrap the connect in withRouter.



You should also have a mapDispatchToProps function. Like this:



const mapDispatchToProps = dispatch => ({
makeDispatch: () => dispatch({ getAppInfo })
})


So, instead of:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);


You should have:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
AppSearchBarWithStylesWithConnect = connect(mapStateToProps, mapDispatchToProps)(AppSearchBarWithStyles);
export default withRouter(AppSearchBarWithStylesWithConnect);


Please see this: https://reacttraining.com/react-router/core/api/withRouter






share|improve this answer























  • Although you may have a point regarding withRouter this is not the problem I was to referring to. Changing the order of connect and withRouter didn't make the problem go away. I do have dispatch method inside getAppInfo. The problem is that the prop update will only be available after the next tick: github.com/reduxjs/react-redux/issues/…
    – hitchhiker
    Nov 21 at 19:27










  • @hitchhiker if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update? Please correct me if I'm wrong. That's indeed an anti-pattern. You really should consider using componentWillReceiveProps or componentDidUpdate. I once made a lil project in the past that helps demonstrate a way to work around this. In the project UI is instantly updated after light calculations on window resize. Please tell me if it helps you and I'll update my answer. Find it here: codesandbox.io/s/233yq699yr
    – Caleb Lucas
    Nov 21 at 21:24










  • @hitchhiker However, if you need to update store immediately, then you really should consider using another middleware. There's redux-saga and redux-observable. I can speak highly of redux-saga because of the way it handles action dispatch and general function calls. It is also very advantageous for testing because it uses generator functions and an object representation of every function call. If you were using saga, then what you want to do would be straightforward with a yield put and then a yield call
    – Caleb Lucas
    Nov 21 at 21:32












  • " if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update" - Yes. However componentWillReceiveProps is now a legacy method and its use is discouraged. I don't want to use other libraries like the ones you mentioned. I think memoization is a technique that can be used here?
    – hitchhiker
    Nov 21 at 21:37










  • Is there a reason why you don't want to use the libraries? For react design patterns they are one of the best. I mean, whether a small or large project. Memoization? Hmmnn.. would be interesting to see how that could be applied to your specific situation.
    – Caleb Lucas
    Nov 21 at 21:39













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401670%2fhow-to-set-react-state-with-new-props-immediately-after-calling-dispatch-via-r%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














From the look of your code you have no dispatch method. If data was really fetched, then you're not getting updates because withRouter actually blocks shouldComponentUpdate. If you want updated state, wrap the connect in withRouter.



You should also have a mapDispatchToProps function. Like this:



const mapDispatchToProps = dispatch => ({
makeDispatch: () => dispatch({ getAppInfo })
})


So, instead of:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);


You should have:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
AppSearchBarWithStylesWithConnect = connect(mapStateToProps, mapDispatchToProps)(AppSearchBarWithStyles);
export default withRouter(AppSearchBarWithStylesWithConnect);


Please see this: https://reacttraining.com/react-router/core/api/withRouter






share|improve this answer























  • Although you may have a point regarding withRouter this is not the problem I was to referring to. Changing the order of connect and withRouter didn't make the problem go away. I do have dispatch method inside getAppInfo. The problem is that the prop update will only be available after the next tick: github.com/reduxjs/react-redux/issues/…
    – hitchhiker
    Nov 21 at 19:27










  • @hitchhiker if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update? Please correct me if I'm wrong. That's indeed an anti-pattern. You really should consider using componentWillReceiveProps or componentDidUpdate. I once made a lil project in the past that helps demonstrate a way to work around this. In the project UI is instantly updated after light calculations on window resize. Please tell me if it helps you and I'll update my answer. Find it here: codesandbox.io/s/233yq699yr
    – Caleb Lucas
    Nov 21 at 21:24










  • @hitchhiker However, if you need to update store immediately, then you really should consider using another middleware. There's redux-saga and redux-observable. I can speak highly of redux-saga because of the way it handles action dispatch and general function calls. It is also very advantageous for testing because it uses generator functions and an object representation of every function call. If you were using saga, then what you want to do would be straightforward with a yield put and then a yield call
    – Caleb Lucas
    Nov 21 at 21:32












  • " if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update" - Yes. However componentWillReceiveProps is now a legacy method and its use is discouraged. I don't want to use other libraries like the ones you mentioned. I think memoization is a technique that can be used here?
    – hitchhiker
    Nov 21 at 21:37










  • Is there a reason why you don't want to use the libraries? For react design patterns they are one of the best. I mean, whether a small or large project. Memoization? Hmmnn.. would be interesting to see how that could be applied to your specific situation.
    – Caleb Lucas
    Nov 21 at 21:39


















0














From the look of your code you have no dispatch method. If data was really fetched, then you're not getting updates because withRouter actually blocks shouldComponentUpdate. If you want updated state, wrap the connect in withRouter.



You should also have a mapDispatchToProps function. Like this:



const mapDispatchToProps = dispatch => ({
makeDispatch: () => dispatch({ getAppInfo })
})


So, instead of:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);


You should have:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
AppSearchBarWithStylesWithConnect = connect(mapStateToProps, mapDispatchToProps)(AppSearchBarWithStyles);
export default withRouter(AppSearchBarWithStylesWithConnect);


Please see this: https://reacttraining.com/react-router/core/api/withRouter






share|improve this answer























  • Although you may have a point regarding withRouter this is not the problem I was to referring to. Changing the order of connect and withRouter didn't make the problem go away. I do have dispatch method inside getAppInfo. The problem is that the prop update will only be available after the next tick: github.com/reduxjs/react-redux/issues/…
    – hitchhiker
    Nov 21 at 19:27










  • @hitchhiker if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update? Please correct me if I'm wrong. That's indeed an anti-pattern. You really should consider using componentWillReceiveProps or componentDidUpdate. I once made a lil project in the past that helps demonstrate a way to work around this. In the project UI is instantly updated after light calculations on window resize. Please tell me if it helps you and I'll update my answer. Find it here: codesandbox.io/s/233yq699yr
    – Caleb Lucas
    Nov 21 at 21:24










  • @hitchhiker However, if you need to update store immediately, then you really should consider using another middleware. There's redux-saga and redux-observable. I can speak highly of redux-saga because of the way it handles action dispatch and general function calls. It is also very advantageous for testing because it uses generator functions and an object representation of every function call. If you were using saga, then what you want to do would be straightforward with a yield put and then a yield call
    – Caleb Lucas
    Nov 21 at 21:32












  • " if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update" - Yes. However componentWillReceiveProps is now a legacy method and its use is discouraged. I don't want to use other libraries like the ones you mentioned. I think memoization is a technique that can be used here?
    – hitchhiker
    Nov 21 at 21:37










  • Is there a reason why you don't want to use the libraries? For react design patterns they are one of the best. I mean, whether a small or large project. Memoization? Hmmnn.. would be interesting to see how that could be applied to your specific situation.
    – Caleb Lucas
    Nov 21 at 21:39
















0












0








0






From the look of your code you have no dispatch method. If data was really fetched, then you're not getting updates because withRouter actually blocks shouldComponentUpdate. If you want updated state, wrap the connect in withRouter.



You should also have a mapDispatchToProps function. Like this:



const mapDispatchToProps = dispatch => ({
makeDispatch: () => dispatch({ getAppInfo })
})


So, instead of:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);


You should have:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
AppSearchBarWithStylesWithConnect = connect(mapStateToProps, mapDispatchToProps)(AppSearchBarWithStyles);
export default withRouter(AppSearchBarWithStylesWithConnect);


Please see this: https://reacttraining.com/react-router/core/api/withRouter






share|improve this answer














From the look of your code you have no dispatch method. If data was really fetched, then you're not getting updates because withRouter actually blocks shouldComponentUpdate. If you want updated state, wrap the connect in withRouter.



You should also have a mapDispatchToProps function. Like this:



const mapDispatchToProps = dispatch => ({
makeDispatch: () => dispatch({ getAppInfo })
})


So, instead of:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);


You should have:



const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
AppSearchBarWithStylesWithConnect = connect(mapStateToProps, mapDispatchToProps)(AppSearchBarWithStyles);
export default withRouter(AppSearchBarWithStylesWithConnect);


Please see this: https://reacttraining.com/react-router/core/api/withRouter







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 at 22:24

























answered Nov 20 at 22:19









Caleb Lucas

665




665












  • Although you may have a point regarding withRouter this is not the problem I was to referring to. Changing the order of connect and withRouter didn't make the problem go away. I do have dispatch method inside getAppInfo. The problem is that the prop update will only be available after the next tick: github.com/reduxjs/react-redux/issues/…
    – hitchhiker
    Nov 21 at 19:27










  • @hitchhiker if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update? Please correct me if I'm wrong. That's indeed an anti-pattern. You really should consider using componentWillReceiveProps or componentDidUpdate. I once made a lil project in the past that helps demonstrate a way to work around this. In the project UI is instantly updated after light calculations on window resize. Please tell me if it helps you and I'll update my answer. Find it here: codesandbox.io/s/233yq699yr
    – Caleb Lucas
    Nov 21 at 21:24










  • @hitchhiker However, if you need to update store immediately, then you really should consider using another middleware. There's redux-saga and redux-observable. I can speak highly of redux-saga because of the way it handles action dispatch and general function calls. It is also very advantageous for testing because it uses generator functions and an object representation of every function call. If you were using saga, then what you want to do would be straightforward with a yield put and then a yield call
    – Caleb Lucas
    Nov 21 at 21:32












  • " if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update" - Yes. However componentWillReceiveProps is now a legacy method and its use is discouraged. I don't want to use other libraries like the ones you mentioned. I think memoization is a technique that can be used here?
    – hitchhiker
    Nov 21 at 21:37










  • Is there a reason why you don't want to use the libraries? For react design patterns they are one of the best. I mean, whether a small or large project. Memoization? Hmmnn.. would be interesting to see how that could be applied to your specific situation.
    – Caleb Lucas
    Nov 21 at 21:39




















  • Although you may have a point regarding withRouter this is not the problem I was to referring to. Changing the order of connect and withRouter didn't make the problem go away. I do have dispatch method inside getAppInfo. The problem is that the prop update will only be available after the next tick: github.com/reduxjs/react-redux/issues/…
    – hitchhiker
    Nov 21 at 19:27










  • @hitchhiker if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update? Please correct me if I'm wrong. That's indeed an anti-pattern. You really should consider using componentWillReceiveProps or componentDidUpdate. I once made a lil project in the past that helps demonstrate a way to work around this. In the project UI is instantly updated after light calculations on window resize. Please tell me if it helps you and I'll update my answer. Find it here: codesandbox.io/s/233yq699yr
    – Caleb Lucas
    Nov 21 at 21:24










  • @hitchhiker However, if you need to update store immediately, then you really should consider using another middleware. There's redux-saga and redux-observable. I can speak highly of redux-saga because of the way it handles action dispatch and general function calls. It is also very advantageous for testing because it uses generator functions and an object representation of every function call. If you were using saga, then what you want to do would be straightforward with a yield put and then a yield call
    – Caleb Lucas
    Nov 21 at 21:32












  • " if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update" - Yes. However componentWillReceiveProps is now a legacy method and its use is discouraged. I don't want to use other libraries like the ones you mentioned. I think memoization is a technique that can be used here?
    – hitchhiker
    Nov 21 at 21:37










  • Is there a reason why you don't want to use the libraries? For react design patterns they are one of the best. I mean, whether a small or large project. Memoization? Hmmnn.. would be interesting to see how that could be applied to your specific situation.
    – Caleb Lucas
    Nov 21 at 21:39


















Although you may have a point regarding withRouter this is not the problem I was to referring to. Changing the order of connect and withRouter didn't make the problem go away. I do have dispatch method inside getAppInfo. The problem is that the prop update will only be available after the next tick: github.com/reduxjs/react-redux/issues/…
– hitchhiker
Nov 21 at 19:27




Although you may have a point regarding withRouter this is not the problem I was to referring to. Changing the order of connect and withRouter didn't make the problem go away. I do have dispatch method inside getAppInfo. The problem is that the prop update will only be available after the next tick: github.com/reduxjs/react-redux/issues/…
– hitchhiker
Nov 21 at 19:27












@hitchhiker if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update? Please correct me if I'm wrong. That's indeed an anti-pattern. You really should consider using componentWillReceiveProps or componentDidUpdate. I once made a lil project in the past that helps demonstrate a way to work around this. In the project UI is instantly updated after light calculations on window resize. Please tell me if it helps you and I'll update my answer. Find it here: codesandbox.io/s/233yq699yr
– Caleb Lucas
Nov 21 at 21:24




@hitchhiker if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update? Please correct me if I'm wrong. That's indeed an anti-pattern. You really should consider using componentWillReceiveProps or componentDidUpdate. I once made a lil project in the past that helps demonstrate a way to work around this. In the project UI is instantly updated after light calculations on window resize. Please tell me if it helps you and I'll update my answer. Find it here: codesandbox.io/s/233yq699yr
– Caleb Lucas
Nov 21 at 21:24












@hitchhiker However, if you need to update store immediately, then you really should consider using another middleware. There's redux-saga and redux-observable. I can speak highly of redux-saga because of the way it handles action dispatch and general function calls. It is also very advantageous for testing because it uses generator functions and an object representation of every function call. If you were using saga, then what you want to do would be straightforward with a yield put and then a yield call
– Caleb Lucas
Nov 21 at 21:32






@hitchhiker However, if you need to update store immediately, then you really should consider using another middleware. There's redux-saga and redux-observable. I can speak highly of redux-saga because of the way it handles action dispatch and general function calls. It is also very advantageous for testing because it uses generator functions and an object representation of every function call. If you were using saga, then what you want to do would be straightforward with a yield put and then a yield call
– Caleb Lucas
Nov 21 at 21:32














" if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update" - Yes. However componentWillReceiveProps is now a legacy method and its use is discouraged. I don't want to use other libraries like the ones you mentioned. I think memoization is a technique that can be used here?
– hitchhiker
Nov 21 at 21:37




" if I understand you, you're trying to synchronously get updated state as props within the function that dispatched global state update" - Yes. However componentWillReceiveProps is now a legacy method and its use is discouraged. I don't want to use other libraries like the ones you mentioned. I think memoization is a technique that can be used here?
– hitchhiker
Nov 21 at 21:37












Is there a reason why you don't want to use the libraries? For react design patterns they are one of the best. I mean, whether a small or large project. Memoization? Hmmnn.. would be interesting to see how that could be applied to your specific situation.
– Caleb Lucas
Nov 21 at 21:39






Is there a reason why you don't want to use the libraries? For react design patterns they are one of the best. I mean, whether a small or large project. Memoization? Hmmnn.. would be interesting to see how that could be applied to your specific situation.
– Caleb Lucas
Nov 21 at 21:39




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401670%2fhow-to-set-react-state-with-new-props-immediately-after-calling-dispatch-via-r%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

TypeError: fit_transform() missing 1 required positional argument: 'X'