web-dev-qa-db-ja.com

ステートレスコンポーネントReact router

React and Redux、私は実際に自分自身のコードを作成していますが、ステートレスコンポーネントの内部でルーターのようなもので立ち往生しました。

したがって、実際にはthis.props.history.Push( '/ somepath')を使用してコンポーネントにルーティングする必要があります。これは、ステートレスコンポーネント内では発生しません。

私のステートレスコンポーネントは

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;

Mainlayoutのような別のステートレスコンポーネント内でこれを呼び出しています

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;

私のメインファイルindex.jsは次のようになります

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);

だから私は必要なのは、このコンポーネントとパスがルーターファイルで指定されているヘッダーから別のコンポーネントにルーティングする必要があることです

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;

ヘッダーからルーティングしようとすると、Push of undefinedなどのエラーが発生しました。ここで行う必要がある変更はありますか?.

前もって感謝します。

5
Krishna

履歴オブジェクトを直接インポートし、そこからプッシュできます。たとえば、以下のコードを試してください。

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;

以下のようなブラウザ履歴を作成し、インポートすることであらゆる場所で使用します。

import createBrowserHistory from 'history/createBrowserHistory';

export default createBrowserHistory({});
1
forJ

2019年、React Router v4はステートレス/機能コンポーネント用のuseHistoryフックを追加しました:

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

ドキュメントから:

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

これが手遅れにならないことを願っています。ステートフルコンポーネントからリダイレクトできましたが、コンポーネントをステートレスコンポーネントに変換したかったのは、ステートフルコンポーネントがリダイレクトビットだけだったからです。私は反応するのがかなり新しいので、そこにあるほとんどのリソースはそれほど明確ではありませんでした。これは私がそれについて行った方法です。

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

WithRouterを使用して(プラスTypeScript警告を無視して)それは私のために働いた:

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

...

type Props = { myProp: boolean };

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

...

})
0
ego