0

I have an following app:

index.js

const store = createStore(rootReducers, applyMiddleware(createLogger()));

store.dispatch(fetchArticles());

ReactDOM.render(
    <Provider store={store}>
        <Router>
            <Switch>
                <Route exact path='/' component={ArticlesPage}/>
                <Route path='/search' component={SearchPage}/>
            </Switch>
        </Router>
    </Provider>,
    document.getElementById('root')
);

ArticlesPage.js

const ArticlesPage = ({groups, onSearch}) => (
    <Grid>
        <SearchBoxWithImages onSearch={onSearch}/>
        <CategorySections groups={groups}/>
    </Grid>
);

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

const mapDispatchToProps = dispatch => ({
    onSearch: (q) => dispatch(searchArticles(q))
});

export default withRouter(connect(
    mapStateToProps,
    mapDispatchToProps
)(ArticlesPage));

fetchArticles and searchArticles are an redux actions.

I wanna handle that case:

  • enter site (url /)
  • after search, handled by a SearchBoxWithImages component, I wanna change an url into /search?q=term (term is a callback from the onSearch handler)
  • call action searchArticles to set redux state

Currently only state was changed (because of call the searchArticles action). Url isn't change, therefore SearchPage container wasn't call.

Piotr Olaszewski
  • 6,017
  • 5
  • 38
  • 65
  • Can't you use history.push in your searchArticles action creator? Or you are using but url is not changing and this is the problem? – devserkan Apr 10 '18 at 21:50
  • I didn't use any history.push methods, because of I don't know how I can do it in the best way. Before using a redux I get router from context, and manage state on my own way, but now I wanna use redux to manage app state. – Piotr Olaszewski Apr 11 '18 at 04:29
  • Look at this question and answers given: https://stackoverflow.com/questions/42701129/how-to-push-to-history-in-react-router-v4/42716055 There are lots of good information. Also, there is an alternative way to change navigation with React Router Redirect: https://reacttraining.com/react-router/web/api/Redirect – devserkan Apr 11 '18 at 11:45

1 Answers1

1

Create a history object like so

import createBrowserHistory from 'history/createBrowserHistory';

export default createBrowserHistory({});

Apply it to your router

import React from 'react';
import {Router, Route, Switch} from 'react-router-dom';
import history from '../services/history';

export default class App extends React.Component {

    render() {
        return (
            <div>
                <Router history={history}>
                    {mainSwitch}
                </Router>
            </div>
        );
    }
}

Wherever you want to programmatically change the route do the following

import history from '/path/to/history'

history.push('/path/you/want/to/go/to')

This can also be called within your redux action so u can call history.push after your action has ended.

forJ
  • 4,309
  • 6
  • 34
  • 60
  • Thanks! Are you think a redux action is the best place to call history manager and push news url? And extra question: is there any way to don't use a third party libs, do it using only a react and redux? – Piotr Olaszewski Apr 11 '18 at 04:24
  • It would be difficult or very messy to do so in your case. However, you can render different component based on state change like in `private route` example in `react router` https://reacttraining.com/react-router/web/example/auth-workflow – forJ Apr 11 '18 at 05:34
  • Please do accept the answer if it were helpful thanks. – forJ Apr 11 '18 at 05:34
  • I found a better pattern using react-router. I can inject into `mapDispatchToProps` history object and use it in the action. – Piotr Olaszewski Apr 17 '18 at 17:14