【问题标题】:Using withRouter in context provider results in error: "Invariant failed: You should not use <Route> outside a <Router>"在上下文提供程序中使用 withRouter 会导致错误:“Invariant failed: You should not use <Route> outside a <Router>”
【发布时间】:2019-05-15 08:14:31
【问题描述】:

我正在 App 中生成路由器组件:

render() {
        return (
            <div className="App container-fluid">
                <CharacterProvider>
                    <Router>
                        <div>
                            <Link to="/new">New Character</Link>
                            <Link to="/load">Load Character</Link>
                            <Route path="/new" component={NewCharacter} />
                            <Route path="/load" component={CharacterSheet} />
                            <Route path="/edit" component={EditCharacter} />
                            <Route exact path="/" component={MenuImages} />
                        </div>
                    </Router>
                </CharacterProvider>
            </div>
        );
    }

但是我需要在提供者组件中包含的函数中推送历史记录:

import React, {Component} from "react";
import {withRouter} from "react-router-dom";
import CharacterDataService from "../service/CharacterDataService";

const CharacterContext = React.createContext()
const CharacterConsumer = CharacterContext.Consumer

class CharacterProvider extends Component {
    constructor(props) {
        super(props);

        this.state = {
            ...
            getCharacter: this.getCharacter,
        }
    }

    getCharacter = (id) => {
        console.log("Getting character...")
        CharacterDataService.getCharacterById(id)
            .then(
                response => {
                    console.log(response);
                    this.setState({
                        ...
                    });
                }
            );
        this.props.history.push('/load');
    }


    render() {
        return (
            <CharacterContext.Provider
                value={this.state}>
               {
                   this.props.children
               }
            </CharacterContext.Provider>
        )
    }
}

export { CharacterContext, CharacterConsumer}
export default withRouter(CharacterProvider)

这样做会导致此堆栈跟踪出错:

tiny-invariant.esm.js:12 Uncaught Error: Invariant failed: You should not use <Route> outside a <Router>
    at invariant (tiny-invariant.esm.js:12)
    at react-router.js:409
    at updateContextConsumer (react-dom.development.js:16085)
    at beginWork (react-dom.development.js:16306)
    at performUnitOfWork (react-dom.development.js:20285)
    at workLoop (react-dom.development.js:20326)
    at HTMLUnknownElement.callCallback (react-dom.development.js:147)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
    at invokeGuardedCallback (react-dom.development.js:250)
    at replayUnitOfWork (react-dom.development.js:19509)
    at renderRoot (react-dom.development.js:20439)
    at performWorkOnRoot (react-dom.development.js:21363)
    at performWork (react-dom.development.js:21273)
    at performSyncWork (react-dom.development.js:21247)
    at requestWork (react-dom.development.js:21102)
    at scheduleWork (react-dom.development.js:20915)
    at scheduleRootUpdate (react-dom.development.js:21610)
    at updateContainerAtExpirationTime (react-dom.development.js:21636)
    at updateContainer (react-dom.development.js:21704)
    at ReactRoot.push../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render (react-dom.development.js:22017)
    at react-dom.development.js:22169
    at unbatchedUpdates (react-dom.development.js:21492)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:22165)
    at Object.render (react-dom.development.js:22240)
    at Module../src/index.js (index.js:8)
    at __webpack_require__ (bootstrap:781)
    at fn (bootstrap:149)
    at Object.0 (serviceWorker.js:135)
    at __webpack_require__ (bootstrap:781)
    at checkDeferredModules (bootstrap:45)
    at Array.webpackJsonpCallback [as push] (bootstrap:32)
    at main.chunk.js:1
invariant @ tiny-invariant.esm.js:12
(anonymous) @ react-router.js:409
updateContextConsumer @ react-dom.development.js:16085
beginWork @ react-dom.development.js:16306
performUnitOfWork @ react-dom.development.js:20285
workLoop @ react-dom.development.js:20326
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
replayUnitOfWork @ react-dom.development.js:19509
renderRoot @ react-dom.development.js:20439
performWorkOnRoot @ react-dom.development.js:21363
performWork @ react-dom.development.js:21273
performSyncWork @ react-dom.development.js:21247
requestWork @ react-dom.development.js:21102
scheduleWork @ react-dom.development.js:20915
scheduleRootUpdate @ react-dom.development.js:21610
updateContainerAtExpirationTime @ react-dom.development.js:21636
updateContainer @ react-dom.development.js:21704
push../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:22017
(anonymous) @ react-dom.development.js:22169
unbatchedUpdates @ react-dom.development.js:21492
legacyRenderSubtreeIntoContainer @ react-dom.development.js:22165
render @ react-dom.development.js:22240
./src/index.js @ index.js:8
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ serviceWorker.js:135
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
Show 2 more frames
index.js:1437 The above error occurred in the <Context.Consumer> component:
    in Route (created by withRouter(CharacterProvider))
    in withRouter(CharacterProvider) (at App.js:41)
    in div (at App.js:40)
    in App (at src/index.js:8)

我正在使用一个更改 Providers 状态的函数 - 但是,由于该函数用于 onClick 操作,我还需要根据触发该操作的元素更改路由。提供者的类在路由器的结构之外,所以我需要一种方法来启用提供者组件中的历史。有没有比使用 withRouter 更好的方法来解决这个问题?我怎么用错了?

【问题讨论】:

    标签: reactjs react-router react-context


    【解决方案1】:

    您收到错误是因为您的 Router 不是 withRouter(CharacterProvider) 的父组件,这是 react-router 的要求。

    尝试更改RouterCharacterProvider 组件的顺序:

    <Router>
        <CharacterProvider>
            { /* The rest of your components */ }
        </CharacterProvider>
    </Router>
    

    【讨论】:

      猜你喜欢
      • 2020-02-20
      • 2020-05-02
      • 2018-09-09
      • 2021-01-28
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多