在history.push()之后,组件未呈现

问题描述 投票:0回答:1

单击按钮,我通过执行history.push()来更改URL

import createHistory from 'history/createBrowserHistory'  
const history = createHistory()  
.  
. some code  
.  
history.push(`/share/${objectId}`)

并希望Route中提到的该URL的组件将呈现,但这不会发生。但是,在刷新时,该组件将按预期呈现。但我不明白为什么一旦URL改变就不会渲染。我已经尝试将组件包装在withRouter中。

import React, {Component} from 'react'  
import {BrowserRouter, Router, Route, Switch, withRouter} from 'react-router-dom'  
import createHistory from 'history/createBrowserHistory'  

import Home from './pages/home'  
import ViewFile from './pages/view-file'  

const history = createHistory()

class App extends Component {
    constructor(props) {
      super(props)
    }

      render() {
      return (
          <BrowserRouter>
              <Switch>
                  <Route exact path={'/'} component={Home}/>
                  <Route path={'/share/:id'} component={withRouter(ViewFile)}/>
              </Switch>
          </BrowserRouter>
      )
  }
}

export default App 

以及在Router传递历史,我认为与使用BrowserRouter相同。

import React, {Component} from 'react'  
import {BrowserRouter, Router, Route, Switch, withRouter} from 'react-router-dom'  
import createHistory from 'history/createBrowserHistory'  

import Home from './pages/home'  
import ViewFile from './pages/view-file'  

const history = createHistory()

class App extends Component {
    constructor(props) {
      super(props)
    }

      render() {
      return (
          <Router history={history}>
              <Switch>
                  <Route exact path={'/'} component={Home}/>
                  <Route path={'/share/:id'} component={ViewFile}/>
              </Switch>
          </Router>
      )
  }
}

export default App 

但是没有运气。谁能解释为什么会这样? P.S我经历了here的答案,但他们没有帮助

reactjs react-router browser-history history.js
1个回答
1
投票

每次调用createHistory()时都会创建新的历史记录。如果你正在使用react-router-dom,你可以简单地使用withRouter HOC,它将通过history向组件提供prop对象。然后你将使用history.push('/'),或者如果它在class componentthis.props.history.push('/')等等。

工作示例:https://codesandbox.io/s/p694ln9j0

路线(在history中定义routes

import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import ScrollIntoView from "../components/ScrollIntoView";

const history = createBrowserHistory();

export default () => (
  <Router history={history}>
    <div>
      <ScrollIntoView>
        <Header />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </Switch>
        <Header />
      </ScrollIntoView>
    </div>
  </Router>
);

components / Header.js(我们想要访问history,但是,有时我们必须使用withRouter,因为像Header这样的组件不在<Route "/example" component={Header}/> HOC中,所以它不知道我们的路由)

import React from "react";
import { withRouter } from "react-router-dom";

const Header = ({ history }) => (
  <header>
    <nav style={{ textAlign: "center" }}>
      <ul style={{ listStyleType: "none" }}>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/")}>Home</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/about")}>About</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/contact")}>Contact</button>
        </li>
      </ul>
    </nav>
  </header>
);

export default withRouter(Header);

components / Home.js(像Home这样的组件知道路由并且已经通过history HOC传递了<Route path="/" component={Home} />对象,因此不需要withRouter

import React from "react";

const Home = ({ history }) => (
  <div className="container">
    <button
      className="uk-button uk-button-danger"
      onClick={() => history.push("/notfound")}
    >
      Not Found
    </button>
    <p>
      ...
    </p>
  </div>
);

export default Home;

但是,如果您不想使用withRouter,那么您可以简单地创建一个history实例,该实例将在需要它的组件之间共享。你将import这个history实例并导航与history.push('/');等。

工作示例:https://codesandbox.io/s/5ymj657k1k

历史(在自己的文件中定义history

import { createBrowserHistory } from "history";

const history = createBrowserHistory();

export default history;

路线(将history导入routes

import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import ScrollIntoView from "../components/ScrollIntoView";
import history from "../history";

export default () => (
  <Router history={history}>
    <div>
      <ScrollIntoView>
        <Header />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </Switch>
        <Header />
      </ScrollIntoView>
    </div>
  </Router>
);

components / Header.js(将history导入Header

import React from "react";
import history from "../history";

const Header = () => (
  <header>
    <nav style={{ textAlign: "center" }}>
      <ul style={{ listStyleType: "none" }}>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/")}>Home</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/about")}>About</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/contact")}>Contact</button>
        </li>
      </ul>
    </nav>
  </header>
);

export default Header;

components / Home.js(仍然知道路由并且已经通过history HOC传递了<Route path="/" component={Home} />对象,因此不需要导入history,但是如果你愿意,你仍然可以导入它 - 只是不要解构historyHome的函数参数)

import React from "react";

const Home = ({ history }) => (
  <div className="container">
    <button
      className="uk-button uk-button-danger"
      onClick={() => history.push("/notfound")}
    >
      Not Found
    </button>
    <p>
      ...
    </p>
  </div>
);

export default Home;

但你可能在想,BrowserRouter怎么样?好吧,BrowserRouter有它自己的内部history对象。我们可以再次使用withRouter访问其history。在这种情况下,我们根本不需要createHistory()

工作示例:https://codesandbox.io/s/ko8pkzvx0o

路线

import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import Notfound from "../components/Notfound";
import ScrollIntoView from "../components/ScrollIntoView";

export default () => (
  <BrowserRouter>
    <div>
      <ScrollIntoView>
        <Header />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
          <Route component={Notfound} />
        </Switch>
        <Header />
      </ScrollIntoView>
    </div>
  </BrowserRouter>
);
© www.soinside.com 2019 - 2024. All rights reserved.