使用React Router在不同页面中渲染组件问题

时间:2019-05-16 12:10:49

标签: reactjs react-router react-router-v4

我正在创建一个个人网站来进行React培训,因为几天后我用React Router渲染组件,就像在单击卡片时渲染博客帖子一样,我一直处于困境。

Eveytime,我单击卡片而不是我得到了正确的数据,但是它在主页的底部,所以我想在新页面上动态打开它,就像我单击博客或新闻中的文章一样

我的卡组件

  render() {
    const { match } = this.props;

    const { data, value } = this.state;
    return (
      <>
        <div>
          {data.map((job, id) => (
            <div key={id}>
              <div key={job._id} className="blog-card">
                <div className="meta">
                  <div className="photo">
                    <img src={job.img} alt="logo" />{" "}
                  </div>

                </div>
                <div className="description">

                  <p> {job.description}</p>
                  <p className="read-more">
                    <p>{job.location}</p>
                    <p>
                      <span className="apply-job">
                        {" "}
                        <Link
                          className="link-apply"
                          to={{
                            pathname: `${match.url}/${job._id}`,
                            state: job
                          }}
                        >
                         go to {job.workplace_name}
                        </Link>{" "}
                      </span>
                    </p>
                  </p>
                </div>
              </div>
            </div>
          ))}
        </div>
        }
        <Route path={`${match.path}/:_id`} component={Articles} />
      </>
    );
  }
}

当我单击转到{job.workplace_name}时,我想在新页面下而不是在卡片组件下呈现该组件


const Articles = ({ location }) => (
    <div>
<h1>Hello</h1>
<h1>{location.state.workplace_name}</h1>
<h2>{location.state.position_name}</h2>
<h2>{location.state.description}</h2>
<h2>{location.state.Compensation}</h2>
    </div>
  )

  export default Articles;

2 个答案:

答案 0 :(得分:1)

当您使用react-router编写应用程序代码时,您应该具有一个顶级组件,该组件负责根据您访问的URL决定要打印哪个屏幕。

应该看起来像这样

import { BrowserRouter } from "react-router-dom";
import { Route, Switch } from "react-router";

const App = () => (
  <Switch>
    <Route exact path="/invoices/dashboard" component={Dashboard} />
    <Route path="/invoices/:id" component={Invoice} />
  </Switch>
);

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  el
);

Switch组件将仅呈现与当前URL匹配的第一个Route。 如果您不使用它,则将显示所有匹配的路由。 在顶层,此功能很有用,可以避免同时显示两个屏幕(有点像您的问题)。


您的最大问题是,您将负责显示博客页面的路径放在了卡组件中。

您的组件层次结构:

Router
└ App
   └ Route+Home (maybe)
      └ Card
         └ Route+Articles

应改为:

Router
└ App
  └ Switch
    ├ Route+Home (maybe)
    │ └ Card
    └ Route+Articles

此外,当您刚要更改位置(url)时,可以像以前一样使用Link组件,或使用从Route组件获得的历史记录道具。

在上面的示例中,仪表板和发票获得“历史记录”属性。

  • history.push(path)将模拟导航
  • history.replace(path)将模拟重定向。

还有更多的https://reacttraining.com/react-router/core/api/history

答案 1 :(得分:0)

据推测,您有一个index.js文件,看起来像这样,或者应该看起来像这样,根据解决方案在其中添加了<BrowserRouter>

import { BrowserRouter } from "react-router-dom";
import { Route, Switch } from "react-router";

const App = () => (
  <Switch>
    <Route exact path="/invoices/dashboard" component={Dashboard} />
    <Route path="/invoices/:id" component={Invoice} />
  </Switch>
);

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  el
);

但是,如果您的index.js文件看起来像这样:

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware, compose } from "redux";
import reduxThunk from "redux-thunk";

import App from "./components/App";
import reducers from "./reducers";

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducers,
  composeEnhancers(applyMiddleware(reduxThunk))
);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector("#root")

因为您创建了一个位于组件层次结构顶层的index.js文件,然后创建了一个App.js文件,如下所示:

import React from "react";
import { Route } from "react-router-dom";
import Dashboard from "./invoices/Dashboard";
import Invoice from "./invoices/Invoice";
import Header from "./Header";

const App = () => {
  return (
    <div className="ui container">
        <div>
          <Header />
          <Route exact path="/invoices/dashboard" component={Dashboard} />
          <Route path="/invoices/:id" component={Invoice} />
        </div>
    </div>
  );
};

export default App;

在这种情况下,您可以在所有exact上使用Route关键字并将其全部封装在<BrowserRouter>内,并确保将其封装在<div>中就像这样:

import React from "react";
import { BrowserRouter, Route } from "react-router-dom";
import Dashboard from "./invoices/Dashboard";
import Invoice from "./invoices/Invoice";
import Header from "./Header";

const App = () => {
  return (
    <div className="ui container">
      <BrowserRouter>
        <div>
          <Header />
          <Route exact path="/invoices/dashboard" component={Dashboard} />
          <Route exact path="/invoices/:id" component={Invoice} />
        </div>
      </BrowserRouter>
    </div>
  );
};

export default App;