我正在创建一个个人网站来进行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;
答案 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;