【问题标题】:react-router-redux and redux-immutable: You cannot change <Router history>; it will be ignoredreact-router-redux 和 redux-immutable: 你不能改变 <Router history>;它将被忽略
【发布时间】:2016-08-09 08:04:43
【问题描述】:

我正在尝试将 react-router-redux 与 redux-immutable 一起使用,但在触发 @@router/LOCATION_CHANGE 操作时出现错误:

action @ 14:19:07.625 @@router/LOCATION_CHANGE 
%c prev state color: #9E9E9E; font-weight: bold Map { "repos": Map { "loading": false, "reposCount": 0 }, "users": Map { "loading": false, "usersCount": 0 }, "router": Map { "locationBeforeTransitions": null } }
%c action color: #03A9F4; font-weight: bold { type: '@@router/LOCATION_CHANGE',
  payload: 
   { pathname: 'blank',
     search: '',
     hash: '',
     state: null,
     action: 'POP',
     key: '5b05pd',
     query: {},
     '$searchBase': { search: '', searchBase: '' } } }
%c next state color: #4CAF50; font-weight: bold Map { "repos": Map { "loading": false, "reposCount": 0 }, "users": Map { "loading": false, "usersCount": 0 }, "router": Map { "locationBeforeTransitions": Map { "pathname": "blank", "search": "", "hash": "", "state": null, "action": "POP", "key": "5b05pd", "query": Map {}, "$searchBase": Map { "search": "", "searchBase": "" } } } }
—— log end ——
<Provider> does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions.
Warning: [react-router] You cannot change <Router history>; it will be ignored

我一直在网上阅读这个问题似乎是由hot loader引起的,但我没有使用它。

代码如下所示:

路线

const routes = (
    <Route path="/" component={AppLayout}>
        <IndexRoute component={Home} />
        <Route path="/users" component={UsersPage} />
        <Route path="/repos" component={ReposPage} />
    </Route>
);

根组件

class Root extends React.Component<RootComponentProps, void> {
  public render() {
    const { store, history, routes } = this.props;
    return (
      <Provider store={store}>
        <div>
          <Router history={history}>
            {routes}
          </Router>
          <DevTools />
        </div>
      </Provider>
    );
  }
}

路由器减速器

const initialRouterReducerState = Immutable.fromJS({
    locationBeforeTransitions: null
});

let routerReducer = (state = initialRouterReducerState, action: any) => {
    if (action.type === LOCATION_CHANGE) {
        return state.merge({
            locationBeforeTransitions: action.payload
        });
    }
    return state;
};

主要

// ...

let history = syncHistoryWithStore(browserHistory, store, {
    selectLocationState: (state: any) => state.get("routing").toJS()
});

render(
    <Root store={store} history={history} routes={routes} />,
    document.getElementById(container)
);

您对导致此问题的原因有什么想法吗?

【问题讨论】:

    标签: reactjs react-router redux immutable.js react-router-redux


    【解决方案1】:

    让我们在这里阅读错误:

    不支持即时更改 store。这是最 您可能会看到此错误,因为您更新到 Redux 2.x 并且 React Redux 2.x 不再自动热重载减速器。看 https://github.com/reactjs/react-redux/releases/tag/v2.0.0 为 迁移说明。

    在您的根组件中,您从道具中获取store,并且在每次路由更改时,它都会重新渲染所有内容。

    https://github.com/reactjs/react-redux/blob/master/docs/api.md#react-router-10

    Provider 应该被渲染为顶级组件。路线会正确更改并传递道具,而提供者将通过单个商店传递所有内容。

    ReactDOM.render(
      <Provider store={store}>
        <Router history={history}>...</Router>
      </Provider>,
      targetEl
    )
    

    供应商应与您的商店一起位于顶部。你应该有许多不同的减速器。

    【讨论】:

    • 是否适用于 react-router 0.13?我正在使用 ^2.2.4
    • 这就是我正在做的已经看看我的根组件代码
    • 我已经更新了上面的代码。 Provider 必须是最高级别的。任何东西都不应高于它。不需要根组件。
    • 对不起,我刚试过,但这似乎不是问题。
    【解决方案2】:

    原来我所有的问题都是jsdom配置错误造成的。我创建了一个 dom.ts 文件,我可以从包含 mocha 单元测试的文件中导入该文件:

    /// <reference path="../src/interfaces/interfaces.d.ts" />
    
    let jsdom = require("jsdom");
    
    // setup the simplest document possible
    let doc = jsdom.jsdom(
        `<!doctype html>
        <html>
            <body>
                <div id="root"/><div>
            </body>
        </html>`,
        {
            url: "http://redux-bootstrap.com/"
        }
    );
    
    // get the window object out of the document
    let win = doc.defaultView;
    
    // set globals for mocha that make access to document and window feel 
    // natural in the test environment
    let g: any = global;
    g.document = doc;
    g.window = win;
    
    // take all properties of the window object and also attach it to the 
    // mocha global object
    propagateToGlobal(win);
    
    // from mocha-jsdom https://github.com/rstacruz/mocha-jsdom/blob/master/index.js#L80
    function propagateToGlobal (window: any) {
      for (let key in window) {
        if (!window.hasOwnProperty(key)) { continue; }
        if (key in global) { continue; }
        g[key] = window[key];
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-04-18
      • 2016-07-26
      • 2018-02-25
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 2017-09-28
      • 2018-07-16
      • 2016-02-22
      相关资源
      最近更新 更多