web-dev-qa-db-fra.com

Composant sans état React router

Je suis nouveau sur React et Redux, je suis en train de créer un code de moi-même mais je suis coincé avec une sorte de routeur dans un composant sans état.

Donc, en fait, je dois router vers un composant en utilisant this.props.history.Push ('/ somepath'). Cela ne se produit pas à l'intérieur d'un composant sans état.

Mon composant sans état est

import React from "react"; // eslint-disable-line no-unused-vars
import "bootstrap/dist/css/bootstrap.min.css";
import "./header.css";

const Header = () => ({

    handleAuthor() {
        this.props.history('/somepath')// this is not working
    },

    render(){
        return (
            <div className = "header">
                <h1 onClick = {this.handleAuthor.bind(this)}>{this.props.headerText}</h1>
            </div>
        );
    } 
});

export default Header;

J'appelle cela à l'intérieur d'un autre composant sans état comme la mise en page principale

import React from "react"; // eslint-disable-line no-unused-vars
import Header from "../header/Header"; // eslint-disable-line no-unused-vars
import Footer from "../footer/Footer"; // eslint-disable-line no-unused-vars
import "./mainLayout.css";

const MainLayout = props => ({
    render() {
        return (
            <div className="App">
                <Header headerText = "RK Boilerplate"/>
                <div className = "mainLayout">
                    <main>{props.children}</main>
                </div>
                <Footer />
            </div>
        );
    }
});

export default MainLayout;

Mon fichier principal index.js ressemble à ceci

import React from "react"; // eslint-disable-line no-unused-vars
import ReactDOM from "react-dom"; // eslint-disable-line no-unused-vars
import { matchRoutes, renderRoutes } from "react-router-config"; // eslint-disable-line no-unused-vars
import { Router } from "react-router-dom"; // eslint-disable-line no-unused-vars
import { Switch } from "react-router"; // eslint-disable-line no-unused-vars
import { Provider } from "react-redux"; // eslint-disable-line no-unused-vars
import store from "./store"; // eslint-disable-line no-unused-vars
import routes from "./routes"; // eslint-disable-line no-unused-vars
import MainLayout from "./components/mainLayout/MainLayout"; // eslint-disable-line no-unused-vars

import createHistory from "history/createBrowserHistory";
let history = createHistory();
const App =  document.getElementById("app");

export default App;

ReactDOM.render(
    <Provider store={store}>
        <MainLayout>
            <Router history= {history}>
                <Switch>
                    {renderRoutes(routes)}
                </Switch>
            </Router>
        </MainLayout>                 
    </Provider>, 
    App);

Donc, ce dont j'ai besoin, c'est que je dois router de l'en-tête vers un autre composant où ce composant et ce chemin sont donnés dans un fichier routeur

router.js

import Home from "../containers/Home";
import About from "../containers/About";
import CreateUser from "../containers/CreateUser";

import Layout from "../containers/Layout";

const routes = [
    { path: "/",
        exact: true,
        component: Layout
    },
    { path: "/home",
        exact: true,
        component: Home
    },
    {
        path:"/About",
        exact: true,
        component: About
    },
    {
        path:"/createUser",
        exact: true,
        component: CreateUser
    }
];

export default routes;

J'ai reçu une erreur comme Push of undefined, lorsque j'ai essayé de router à partir de l'en-tête. Suis-je en train de manquer quelque chose, y a-t-il un changement que je devrais faire ici.

Merci d'avance.

5
Krishna

Vous pouvez importer directement l'objet historique et pousser à partir de cela. Par exemple, essayez le code ci-dessous.

import React from "react"; // eslint-disable-line no-unused-vars
import "bootstrap/dist/css/bootstrap.min.css";
import "./header.css";
import history from "/your/history/path" //try this

const Header = () => ({

    handleAuthor() {
        history.Push('/somepath')// change to this
    },

    render(){
        return (
            <div className = "header">
                <h1 onClick = {this.handleAuthor.bind(this)}>{this.props.headerText}</h1>
            </div>
        );
    } 
});

export default Header;

Créez l'historique du navigateur comme ci-dessous et utilisez-le partout en important.

import createBrowserHistory from 'history/createBrowserHistory';

export default createBrowserHistory({});
1
forJ

En 2019, React Router v4 a maintenant ajouté le hook useHistory pour les composants sans état/fonctionnels:

https://reacttraining.com/react-router/web/api/Hooks/usehistory

De la documentation:

import { useHistory } from "react-router-dom";

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.Push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}
5
Niko Dunk

J'espère que cela n'arrivera pas trop tard. J'ai réussi à rediriger à partir d'un composant avec état, mais je voulais convertir mon composant en composant sans état car la seule chose qui le rendait avec état était le bit de redirection. Je suis assez nouveau pour réagir et la plupart des ressources n'étaient pas aussi claires. C'est ainsi que je l'ai fait.

import React from "react"; // eslint-disable-line no-unused-vars
import "bootstrap/dist/css/bootstrap.min.css";
import "./header.css";

const Header = (props) => {
    return (
        <div className = "header">
            <h1 onClick = {props.history.Push('/some-path')}>{props.headerText}</h1>
        </div>
    );
} 

export default Header;
1
Denis Gathondu

Cela a fonctionné pour moi en utilisant withRouter, (plus en ignorant l'avertissement TypeScript):

import { withRouter } from 'react-router-dom';

...

type Props = { myProp: boolean };

// @ts-ignore
export const MyComponent: FC<Props> = withRouter(({ myProp, history }) => {

...

})
0
ego