React入门实战页面跳转(附完整代码)
Posted 安之ccy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React入门实战页面跳转(附完整代码)相关的知识,希望对你有一定的参考价值。
React入门实战二,通过此练习掌握如下知识点:
- React路由跳转、路由参数等 —— react-router-dom
- axios请求数据
- 生命周期钩子componentDidMount的使用
数据使用:用第三方接口JsonPlaceHolder的 posts 数据,字段如下:
字段名 | 描述 |
---|---|
userId | 用户ID |
id | 数据ID |
title | post标题 |
body | post内容 |
涉及的组件:
组件 | 描述 |
---|---|
App.js | 主组件 |
Home.js | 展示Post |
Navbar.js | 导航栏 |
About.js | 辅助路由的效果展示 |
Contact.js | 辅助路由的效果展示 |
SinglePost.js | post详情页(单条post记录展示) |
基本搭建
先搭一下各个组件,由于导航栏和About组件只是用于展示的,所以使用UI组件;其他组件涉及的功能较为复杂,均为容器组件
App.js:
// 引入必要的组件
import React, { Component } from 'react'
import Navbar from './Navbar'
class App extends Component {
render() {
return (
<div className="App">
<Navbar />
</div>
);
}
}
export default App;
Home.js组件:
import React, { Component } from 'react'
class Home extends Component {
render() {
return (
<div className='container home'>
<h1 className='center'>这是Home页面</h1>
</div>
)
}
}
export default Home
About.js组件、Contact.js组件和Home组件一样,都只是显示一句话:这是About /Contact页面,就不列举了
Navbar.js,导航栏,在右侧设置三个组件的链接:Home、About、Contact
import React from 'react'
const Navbar = () => {
return (
<nav className='nav-wrapper red darken-3'>
<div className='container'>
<a href='/' className='brand-logo'>React入门实战(二)</a>
<ul className='right'>
<li><a href='/'>Home页面</a></li>
<li><a href='/about'>About页面</a></li>
<li><a href='/contact'>Contact页面</a></li>
</ul>
</div>
</nav>
)
}
export default Navbar
SinglePost组件先不写
先来看看效果:
路由设置:
添加路由,实现点击Home、About、Contact三个页面切换的效果
App.js:
// 引入路由库
import { Route, BrowserRouter } from 'react-router-dom'
// 引入子组件
import Home from './Home';
import About from './About';
import Contact from './Contact';
// Route标签设置跳转路径
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Navbar />
</div>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
</BrowserRouter>
);
}
}
export default App;
点击“About页面”即可切换到About页面,但每次点击都会再刷新一次页面,如果只是想跳转,不需要重新加载渲染,可以使用Link标签,减少DOM性能消耗(Link标签会被渲染成a标签,但节省了很多性能,还有一个Navlink标签,当链接被选中时,增加一个native的className)
用Link标签对导航栏中的三个跳转路径做修改(需引入react-router-dom库)
<ul className='right'>
<li><Link to='/'>Home页面</Link></li>
<li><Link to='/about'>About页面</Link></li>
<li><Link to='/contact'>Contact页面</Link></li>
</ul>
效果:可以看到,切换页面时左上角那个刷新图标没有转动,即没有重新加载
axios请求数据与钩子函数componentDidMount()使用
- 在Home页面装载完毕时,通过axios向JsonPlaceHolder发起数据请求;
- 数据请求的过程在钩子函数componentDidMount()中进行;
- 当axios请求得到回应,记为res,其中的data字段就是我们需要的数据,由于数据较多,只存储前20条记录;
- 将得到的数据记录到state中(方便在render函数中取用);
- 如果得到posts数据,就用JSX语法处理后渲染展示;否则提示正在加载中。
import React, { Component } from 'react'
import axios from 'axios'
class Home extends Component {
state = {
posts: null
}
componentDidMount() {
// 向第三方库请求数据并保存到state中
axios.get("http://jsonplaceholder.typicode.com/posts").then(res => {
this.setState({
posts: res.data.splice(0, 20)
})
})
}
render() {
// 处理获得的数据
const { posts } = this.state;
// 如果得到posts数据,就用JSX语法处理后渲染展示;否则提示正在加载中
const postsList = posts ? (
posts.map(post => {
return (
<div className='card post' key={post.id}>
<div className='card-content'>
<h3 className='card-title'>{post.title}</h3>
<p className='card-action'>{post.body}</p>
</div>
</div>
)
})
) : (
<p className='center'>加载信息中,请稍候......</p>
)
return (
< div className='container' >
<h1 className='center'>这是Home页面</h1>
{postsList}
</div >
)
}
}
export default Home;
效果:展示出posts信息
单条post详情页:路由参数
- 设置详情页的路由表
- 点击某条post,就跳转到这条记录的详情页——Link标签与路由参数的使用
- 详情页组件接收到路由参数,向第三方库请求数据,得到数据后展示
- 为防止一个路由参数匹配到多条路径,使用Switch标签——只匹配单条路由
App.js 设置详情页路由,设置Switch匹配单条路径
<Switch>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
{/*详情页路由*/}
<Route path='/:post_id' component={SinglePost} />
</Switch>
新建SinglePost.js,作为详情页组件
import React, { Component } from 'react'
import axios from 'axios'
class SinglePost extends Component {
state = {
post: []
}
componentDidMount() {
// 请求单页数据并存储到state
const post_id = this.props.match.params.post_id
axios.get("http://jsonplaceholder.typicode.com/posts/" + post_id).then(res => {
this.setState({
post: res.data
})
})
}
render() {
// 从state中取出数据并加工
const { post } = this.state;
const postShow = post ? (
<div className='collection-item' key={post.id}>
<h3 className='center'>{post.title}</h3>
<p>{post.body}</p>
</div>
) : (
<div className='center'>还在加载中......</div>
)
return (
<div className='container'>
<div className='collection'>
{postShow}
</div>
</div>
)
}
}
export default SinglePost;
在Home.js中,将post的title部分包裹上Link标签,让用户可以点击跳转
<Link to={'/' + post.id}>
<h3 className='card-title'>{post.title}</h3>
</Link>
最后再加上图片背景,在index.css中加样式
最终效果如下:
完整代码
App.js:
import React, { Component } from 'react'
import Navbar from './Navbar';
import { Route, BrowserRouter, Switch } from 'react-router-dom'
import Home from './Home';
import About from './About';
import Contact from './Contact';
import SinglePost from './SinglePost';
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Navbar />
</div>
<Switch>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
<Route path='/:post_id' component={SinglePost} />
</Switch>
</BrowserRouter>
);
}
}
export default App;
Home.js
import React, { Component } from 'react'
import axios from 'axios'
import { Link } from 'react-router-dom'
import MyImg from './1.jpg'
class Home extends Component {
state = {
posts: null
}
componentDidMount() {
// 向第三方库请求数据并保存到state中
axios.get("http://jsonplaceholder.typicode.com/posts").then(res => {
this.setState({
posts: res.data.splice(0, 20)
})
})
}
render() {
// 解构
const { posts } = this.state;
const postsList = posts ? (
posts.map(post => {
return (
<div className='card post' key={post.id}>
<img src={MyImg} />
<div className='card-content'>
<Link to={'/' + post.id}>
<h3 className='card-title title center'>{post.title}</h3>
</Link>
<p className='card-action'>{post.body}</p>
</div>
</div>
)
})
) : (
<p className='center'>加载信息中,请稍候......</p>
)
return (
< div className='container home' >
<h1 className='center'>这是Home页面</h1>
{postsList}
</div >
)
}
}
export default Home;
Navbar.js:
import React from 'react'
import {Link} from 'react-router-dom'
const Navbar = () => {
return (
<nav className='nav-wrapper red darken-3'>
<div className='container'>
<a href='/'className='brand-logo'>React入门实战(二)</a>
<ul className='right'>
<li><Link to='/'>Home页面</Link></li>
<li><Link to='/about'>About页面</Link></li>
<li><Link to='/contact'>Contact页面</Link></li>
</ul>
</div>
</nav>
)
}
export default Navbar;
About.js:
import React from 'react'
const About = ()=>{
return (
<div className='container'>
<h1 className='center'>这是About页面</h1>
</div>
)
}
export default About;
Contact.js:
import React from 'react'
const Contact = () => {
return (
<div className='container'>
<h1 className='center'>这是Contact页面</h1>
</div>
)
}
export default Contact;
Single.js的全部代码在上文已经完整给出,这里不再重复
index.css文件里添加以下样式:
.home .post img {
width: 20%;
position: absolute;
top: 10px;
left:7px;
opacity: 0.5;
}
.home .post .title {
padding-left:150px
}
以上是关于React入门实战页面跳转(附完整代码)的主要内容,如果未能解决你的问题,请参考以下文章