react-router-redux,push方法不起作用

时间:2017-03-14 11:30:14

标签: reactjs redux react-router-redux

我正在使用react-router-redux。

我不知道如何创建演示来简单地描述问题。 我在Github上推送所有代码。 https://github.com/jiexishede/newReactSOAskDemo001

a-href效果很好。 @ https://github.com/jiexishede/newReactSOAskDemo001/blob/ask1/src/components/Home/Preview.js/#L37

现在,推送方法不起作用 @ https://github.com/jiexishede/newReactSOAskDemo001/blob/ask1/src/components/Home/Preview.js/#L30

我编辑代码并在GitHub上更新。

我导入hashHistory

https://github.com/jiexishede/newReactSOAskDemo001/blob/286fc0e07f9d9c863f7c4fc8d9b2c09a2c45e231/src/components/Home/Preview.js#L9

hashHistory.push('detail/'+id);效果很好。 https://github.com/jiexishede/newReactSOAskDemo001/blob/286fc0e07f9d9c863f7c4fc8d9b2c09a2c45e231/src/components/Home/Preview.js#L32

disPatchpush @ https://github.com/jiexishede/newReactSOAskDemo001/blob/286fc0e07f9d9c863f7c4fc8d9b2c09a2c45e231/src/components/Home/Preview.js#L31 它不起作用。

Home.js

  @connect(state => {
  return {
    list:state.home.list,

  };
}, dispatch => {

  return {
    actions: bindActionCreators(actions, dispatch),
    dispatchPush:  bindActionCreators(push, dispatch),
  }
})

dispatchPush已从Home.js传递到PreviewListPreview

5 个答案:

答案 0 :(得分:3)

你试过了吗?

handleClick(e) {
   e.preventDefault();
   this.props.history.push('/#/detail/' + id);

}

告诉我它是否有效,并会相应地更新答案。

或者,如果您想尝试在组件之外导航,请尝试this

还尝试设置路线:

 <Route path="/preview" component={Preview} />

这可能会让你成为历史道具。

答案 1 :(得分:1)

你错过了routerMiddleware。应用routerMiddleware后,可以很好地工作。

import { browserHistory } from 'react-router';
import { routerReducer, routerMiddleware } from 'react-router-redux';
...
const finalCreateStore = compose(
  applyMiddleware(
      ThunkMiddleware, 
      FetchMiddleware, 
      routerMiddleware(browserHistory)
  ),
  DevTools.instrument(),
)(createStore);


const reducer = combineReducers({
  ...rootReducer,
  routing: routerReducer,
});

export default function configureStore(initialState) {
  const store = finalCreateStore(reducer, initialState);
  return store;
}

阅读文档的这一部分 - https://github.com/reactjs/react-router-redux#what-if-i-want-to-issue-navigation-events-via-redux-actions

答案 2 :(得分:0)

如果您想要导航到其他路线,请尝试Proptypes,如下所示:

import React, { Component, PropTypes } from 'react';

class Preview extends Component {
        ...
  static contextTypes = {
    router: PropTypes.object
  };
  handleNavigate(id,e) {
    e.preventDefault();
    this.context.router.push(`/#/detail/${id}`);
  }
        ...
}

答案 3 :(得分:0)

我在react-router-redux中遇到了同样的问题,并通过以下方式解决了。

需要使用Router而不是BrowserRouterhistory对象必须使用从createBrowserHistory包导入的history方法创建。

然后必须使用从syncHistoryWithStore导入的react-router-redux方法将历史记录与商店同步。这个新的历史记录对象将传递到Router

然后初始化routerMiddleware,将同步的历史记录对象传递给它。

请查看以下代码:

store.js

import createSagaMiddleware from 'redux-saga';
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import { routerReducer, routerMiddleware as reduxRouterMiddleware } from 'react-router-redux';
import { category, machine, machines, core } from './reducers';
import rootSaga from './sagas';

const rootReducer = combineReducers({
    category,
    machines,
    machine,
    core,
    routing: routerReducer,
});


const initStore = (history = {}) => {
    const sagaMiddleware = createSagaMiddleware();
    const routerMiddleware = reduxRouterMiddleware(history);

    const store = createStore(
        rootReducer, 
        applyMiddleware(
            sagaMiddleware, 
            routerMiddleware
        )
    );

    sagaMiddleware.run(rootSaga);

    return store;
}

export default initStore;

app.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router';
import { Provider } from 'react-redux';
import { createBrowserHistory } from 'history';
import { syncHistoryWithStore } from 'react-router-redux';

import './index.css';
import App from './App';
import initStore from './store';
import * as serviceWorker from './serviceWorker';

const browserHistory = createBrowserHistory();

const store = initStore(browserHistory)
const history = syncHistoryWithStore(browserHistory, store);

ReactDOM.render(
    <Provider store={store}>
        <Router history={history}>
            <App />
        </Router>
    </Provider>,
    document.getElementById('root')
);

serviceWorker.unregister();

答案 4 :(得分:0)

连接的React Router需要React 16.4和React Redux 6.0或更高版本。

$ npm install --save connected-react-router

$ yarn add connected-react-router

用法 步骤1

在您的root reducer文件中,

创建一个将历史作为参数并返回根减速器的函数。 通过将历史记录传递给connectRouter,将Router Reducer添加到root Reducer中。 注意:密钥必须是路由器。

// reducers.js

import { combineReducers } from 'redux'
import { connectRouter } from 'connected-react-router'

const createRootReducer = (history) => combineReducers({
  router: connectRouter(history),
  ... // rest of your reducers
})
export default createRootReducer

第2步

创建Redux存储区时,

创建一个历史对象。 将创建的历史记录提供给root reducer创建者。 如果您要调度历史记录操作(例如,使用push('/ path / to / somewhere')更改URL),请使用routerMiddleware(history)。

// configureStore.js

import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { routerMiddleware } from 'connected-react-router'
import createRootReducer from './reducers'
...
export const history = createBrowserHistory()

export default function configureStore(preloadedState) {
  const store = createStore(
    createRootReducer(history), // root reducer with router state
    preloadedState,
    compose(
      applyMiddleware(
        routerMiddleware(history), // for dispatching history actions
        // ... other middlewares ...
      ),
    ),
  )

  return store
}

第3步

用ConnectedRouter包装您的react-router v4 / v5路由,并将历史对象作为道具传递。切记要删除BrowserRouter或NativeRouter的任何用法,否则将导致同步状态时出现问题。 将ConnectedRouter放置为react-redux的Provider的子代。 N.B.如果要进行服务器端渲染,则仍应使用服务器上react-router中的StaticRouter。

// index.js

import { Provider } from 'react-redux'
import { Route, Switch } from 'react-router' // react-router v4/v5
import { ConnectedRouter } from 'connected-react-router'
import configureStore, { history } from './configureStore'
...
const store = configureStore(/* provide initial state if any */)

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}> { /* place ConnectedRouter under Provider */ }
      <> { /* your usual react-router v4/v5 routing */ }
        <Switch>
          <Route exact path="/" render={() => (<div>Match</div>)} />
          <Route render={() => (<div>Miss</div>)} />
        </Switch>
      </>
    </ConnectedRouter>
  </Provider>,
  document.getElementById('react-root')
)