J'ai un problème avec Link. Googlé beaucoup de sujets, mais je n'ai pas eu une réponse correcte. Dans une discussion, le problème se situe dans la version précédente du routeur, dans l'autre dans la mauvaise importation de composants, dans la troisième, la réponse n'a même pas été annoncée.
Aussi, qu'est-ce que c'est avec l'histoire?
Versions des composants:
"react": "^15.4",
"react-dom": "^15.4",
"react-router": "^4.1.1",
"react-router-dom": "^4.1.1"
Les erreurs sont:
Warning: Failed context type: The context `router` is marked as required in `Link`,
but its value is `undefined`.
et
Uncaught TypeError: Cannot read property 'history' of undefined
Le composant où Link est utilisé est assez primitif:
import React from 'react';
import { Link } from 'react-router-dom';
export default class Menu extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<ul>
<li><Link to="/one">1</Link></li>
<li><Link to="/two">2</Link></li>
<li><Link to="/three">3</Link></li>
<li><Link to="/four">4</Link></li>
</ul>
</div>
);
}
}
Donc, le composant avec le routeur ressemble à:
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom'
import Page1 from './Page1';
import Page2 from './Page2';
import Page3 from './Page3';
import Page4 from './Page4';
export default class Routes extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<BrowserRouter text = {this.props.text}>
<Route path = "/one"
render={(props) => (
<Page1 text = {this.props.text.Page1} {...props} />)} />
<Route path = "/two"
render={(props) => (
<Page2 text = {this.props.text.Page2} {...props} />)} />
<Route path = "/three"
render={(props) => (
<Page3 text = {this.props.text.Page3} {...props} />)} />
<Route path = "/four"
render={(props) => (
<Page4 text = {this.props.text.Page4} {...props} />)} />
</BrowserRouter>
);
}
}
Et le composant le plus racine de l'application:
import Header from './pages/menu/Header';
import Routes from './Routes';
const texts = require('text.json');
sessionStorage.setItem('lang','UA');
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
text: texts.UA
};
this.langHandler = this.langHandler.bind(this);
}
langHandler() {
if (sessionStorage.lang === 'UA') {
sessionStorage.setItem('lang','RU');
this.setState({ text: texts.RU })
} else {
sessionStorage.setItem('lang','UA');
this.setState({ text: texts.UA })
}
}
render() {
return (
<div id="content">
<Header changeLang = {this.langHandler}
text = {this.state.text.header}/>
<Routes text = {this.state.text}/>
</div>
);
}
}
En bref, le fait est que la page a toujours un en-tête de rendu, et en dessous de celui-ci, en fonction de l'élément de menu sélectionné, le composant correspondant a été rendu.
Je serai reconnaissant pour tout conseil.
Votre composant Menu doit être imbriqué dans le composant BrowserRouter pour que les liens fonctionnent dans ce contexte de routeur.
Veuillez consulter l'exemple de base: https://reacttraining.com/react-router/web/example/basic
Vous devez utiliser <Link>
uniquement dans la balise <Router>
; si c'est en dehors de cela, vous obtiendrez cette erreur.
const Links =()=>(
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
)
const App=()=>(
<Links/> <==== this will throw Error
<Router>
<div>
<Route path="/" component={Home} />
<Route path="/" component={About} />
</div>
</Router>
)
suivre est la bonne façon ...
const Links =()=>(
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
)
const App=()=>(
<Router>
<div>
<Links/> <==== this will through Error
<Route path="/" component={Home} />
<Route path="/" component={About} />
</div>
</Router>
)
Nous supposons que nous avons les éléments suivants:
import { BrowserRouter as StaticRouter, Router, Switch, Route, Link } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
const customHistory = createBrowserHistory();
Ensuite, il semble qu'il soit nécessaire d'envelopper chaque bloc imbriqué de liens avec
<Router history={customHistory}>
<div>
<Link to={'/.../' + linkName1}>
{itemName1}
</Link>
<Link to={'/.../' + linkName2}>
{itemName2}
</Link>
</div>
</Router>