React入门实战页面跳转(附完整代码)

Posted 安之ccy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React入门实战页面跳转(附完整代码)相关的知识,希望对你有一定的参考价值。

React入门实战二,通过此练习掌握如下知识点:

  • React路由跳转、路由参数等 —— react-router-dom
  • axios请求数据
  • 生命周期钩子componentDidMount的使用

数据使用:用第三方接口JsonPlaceHolder的 posts 数据,字段如下:

字段名描述
userId用户ID
id数据ID
titlepost标题
bodypost内容

涉及的组件:

组件描述
App.js主组件
Home.js展示Post
Navbar.js导航栏
About.js辅助路由的效果展示
Contact.js辅助路由的效果展示
SinglePost.jspost详情页(单条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入门实战页面跳转(附完整代码)的主要内容,如果未能解决你的问题,请参考以下文章

React入门实战联系人列表Contact(附完整代码)

React入门实战联系人列表Contact(附完整代码)

知识图谱完整项目实战(附源码)

天池赛题解析:零基础入门语义分割-地表建筑物识别-CV语义分割实战(附部分代码)

Python应用实战案例-Pythongeopandas包详解(附大量案例及代码)

BIM入门实战Navisworks2018简体中文安装教程(附安装包下载)