Использование withRouter в провайдере контекста приводит к ошибке: «Инвариант не выполнен: вы не должны использовать <Route>за пределами <Router>» - PullRequest
0 голосов
/ 15 мая 2019

Я генерирую компоненты маршрутизатора в приложении:

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)

Я использую функцию, которая изменяет состояние провайдеров - однако, поскольку функция используется в действии onClick, мне также нужно изменить маршрут в соответствии ск элементу, который запустил действие.Класс провайдера находится за пределами структуры маршрутизатора, поэтому мне нужен способ включить историю в компоненте провайдера.Есть ли лучший способ решить проблему, чем использовать withRouter?Как я использую это неправильно?

1 Ответ

1 голос
/ 15 мая 2019

Вы получаете сообщение об ошибке, потому что ваш Router не является родительским компонентом вашего withRouter(CharacterProvider), который требует react-router.

Попробуйте изменить порядок ваших Router и CharacterProviderкомпоненты:

<Router>
    <CharacterProvider>
        { /* The rest of your components */ }
    </CharacterProvider>
</Router>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...