我有一个包含主要组件的react应用。 ,其中包含带有导航栏标记的元素。
//app.js
import React, { Component } from 'react';
import {
Route,
NavLink,
BrowserRouter,
Switch,
} from "react-router-dom";
import Home from './components/home';
import Create from './components/create';
import './App.css';
const pathBase = 'http://127.0.0.1:8000';
const pathSearch = '/posts/';
class App extends Component {
constructor(props) {
super(props);
this.state = {
posts: [],
post: null,
error: null,
}
}
setPostsState = result => {
this.setState({ posts: result})
}
setPostState = post => {
this.setState({ post: post});
console.log(this.state.post)
}
retrievePost = (event, post) => {
event.preventDefault();
this.fetchPost(post);
}
deletePosts = id => {
fetch(`${pathBase}${pathSearch}${id }`, { method: 'DELETE'})
.then(res => res.status === 204 ? this.fetchPosts() : null)
}
editPosts = id => {
fetch(`${pathBase}${pathSearch}${id }`, { method: 'PUT'})
.then(res => res.status === 204 ? this.fetchPosts() : null)
}
fetchPost = (post) => {
fetch(`${pathBase}${pathSearch}${post.id}`)
.then(response => response.json())
.then(result => this.setPostState(result))
.catch(error => console.log(error));
}
fetchPosts = () => {
fetch(`${pathBase}${pathSearch}`)
.then(response => response.json())
.then(result => this.setPostsState(result))
.catch(error => this.setState({ error: error }));
}
componentDidMount() {
this.fetchPosts();
}
render() {
const { posts, error } = this.state;
if (error) {
return <div className="container">
<h3>Error: {error.message}</h3>
</div>;
}
return (
<BrowserRouter>
<div className="container">
<header>
<nav className="navbar navbar-expand-md navbar-light bg-light">
<a className="navbar-brand" href="">Django Rest API</a>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item active">
<NavLink to="/posts">Posts</NavLink>
</li>
<li className="nav-item">
<NavLink to="/create">Create</NavLink>
</li>
</ul>
</div>
</nav>
</header>
<Switch>
<Route path="/create"
render={(props) =>
<Create {...props}
fetchPosts={this.fetchPosts}
/>
}
/>
<Route path="/posts"
render={(props) =>
<Home {...props}
posts={posts}
deletePost={this.deletePosts}
/>
}
/>
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
还有一个(使用React-Router v4),其中path =“ / posts”呈现了一个Component。该组件由一个列表组成,该列表映射了从数据库获得的博客文章。每个帖子均显示为卡片,并带有帖子名称作为链接,当用户单击时,应调出组件以显示帖子详细信息。
// components/home.js
import React, { Component } from 'react';
import Post from './post';
import {
Route,
NavLink,
} from "react-router-dom";
class Home extends Component {
render() {
const ulStyle = { listStyleType: 'none' }
const { deletePost, posts } = this.props;
const match = this.props;
console.log(match)
return (
<ul style={ ulStyle }>
<h3>Posts</h3>
{posts.map(post =>
<li
key={posts.indexOf(post)}
value={post.id}
>
<div className="card">
<div className="card-body">
<NavLink to={`/posts/${post.id}`}>{post.title}
</NavLink>, Created: {post.timestamp}
<button type="button"
onClick={() => deletePost(post.id)}
className="float-right btn btn-outline-danger btn-sm"
>
Delete
</button>
</div>
</div>
</li>
)}
<Route exact path={`/posts/:postId`} render={(props) =>
(<Post {...props} posts={posts}/>)}/>
</ul>
);
}
}
export default Home;
我无法让post组件在新页面上呈现。当前,如果用户单击链接,则组件将在现有页面(组件)的底部呈现。我需要Post组件在一个全新的页面上呈现。我是怎么做到的?
import React, { Component } from 'react';
class Post extends Component {
render() {
const { children, match, posts} = this.props;
console.log(match);
console.log(posts);
const p = (posts) => {
posts.find(post => post === match.postId)
}
return (
<div>
{match.params.postId}
<p>HELLO WORLD</p>
</div>
);
}
}
export default Post;
答案 0 :(得分:1)
您看到的是React Router嵌套路由的预期行为。嵌套路由的内容将作为其父组件的一部分呈现。
这样设计,以便在导航时重新渲染的次数保持最少(当嵌套路线更改时,父组件的内容不会重新渲染)。
如果要更改整个页面的内容,则不应使用嵌套路由。只需将您拥有的所有路线放在Switch
组件下。换句话说,将您的单个发布路线移至App
组件。
答案 1 :(得分:0)
您应该对路由器组件有一个div。例如
<Router>
<div className = "app">
<nav />
<div className = "container">
//routes to be render here
<Route exact path = "/sample" component = {Sample} />
</div>
<footer />
</div>
</Router>
,以便该组件将在页面中间呈现,并在路线更改时删除当前组件。