ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

React_day04_react路由、组件间通信、新闻网站构建

2021-11-17 16:59:12  阅读:100  来源: 互联网

标签:react res day04 间通信 item import data id


1.版本兼容相关问题

又是一次实际上手和教程版本不一致的采坑过程,前后也废了不少周折。
实际开发时React17,react-dom-router 6.x, antd 4.x
教程版本React16,react-dom-router 5.x, antd 3.x
一开始是想安装新版本一点点解决bug的,可是太耗时最终还是选择了降低版本,在package.json里修改相关版本号后terminal中重新npm install
也还是总结下相关的坑
(1)路由相关兼容问题
react-dom-router 5.x -> 6.x
第一个报错需要用routes把route包裹

//5.x
            <BrowserRouter>
                <div>
                    {/*list后面有参数,会放到id里面*/}
                    <Route path="/list/:id" component= {Newlist}/>

                     <Route path = "/newButton" component = {NewButton}/>

                </div>
            </BrowserRouter>
//6.x
   <BrowserRouter>
    <Routes>

      <Route path="/list" element={<Newlist />} />
      <Route path="/newButton" element={<NewButton />} />
    </Routes>
  </BrowserRouter>

接下来与取消component对应的是无法从props获取参数

//5.x
                    <Route path="/list/:id" component= {Newlist}/>

                     <Route path = "/newButton" component = {NewButton}/>
------------------------------------------------------------------------
class Newlist extends Component{
    render() {
    //获取props里match参数,url参数
        console.log(this.props.match.params.id)
        }
        }
//6.x
import { useParams } from 'react-router-dom';
export default function Newlist(){
    const params = useParams();
    return (
        <div>
            <h1>{params.id}</h1>
        </div>
    )
}

2.React路由

react-router-dom 5.x的路由配置:
(1)import相关包

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

(2)在组件中配置path属性
如果当前path匹配,则会跳转至path相应的组件
另外要注意根目录要放在后面,
如果在几个最前,其他的路径如/detail也是会和/匹配造成错误

                <Content className = 'content'>

                    <Switch>
                        /
                    {/* Switch  匹配一个不会继续匹配   */}
                    <Route path='/detail' component={Detail}/>
                    {/*访问根目录,如果/在前那么detail和根路径也会匹配,/显示出根路径 现在detail在前,如果是根路径和detail匹配不上 */}
                    <Route path = '/:id?' component = {List}/>
                    {/*/id可不传*/}
                    </Switch>

                </Content>

(3) 实现点击按钮显示对应的组件(列表、页面等)
在新闻网站上方的导航栏组件中每个标题的button绑定一个
header

import React, {Component, Fragment} from 'react';
import logo from'./logo.png'
import './style.css'
import {Menu   } from "antd";
import { Icon } from '@ant-design/compatible';
import {Link} from 'react-router-dom'
import axios from 'axios';

class AppHeader extends Component{
    constructor(props) {
        super(props);
        this.state = {
            list :[]
        }

    }

    getMenuItems(){
        return this.state.list.map(item =>{
            return (<Menu.Item key={ item.id }   >
                {/*Link需要在Router内部*/}
                <Link to = {`/${item.id}`}>
                    <Icon type = {item.icon} />
                    {item.title}
                </Link>

            </Menu.Item>)
        })

    }
    componentDidMount() {
        axios.get('http://www.dell-lee.com/react/api/header.json')
            .then((res) =>{
                this.setState({
                    list : res.data.data
                })
            })
    }

    render() {
        return (
           <Fragment>
            <img src = {logo} className='app-header-logo'/>
            <Menu
                mode="horizontal"
                className = 'app-header-menu'>
                {this.getMenuItems()}

            </Menu>
            </Fragment>
            )
    }
}

export default AppHeader;

首页效果图
在这里插入图片描述

3.新闻网站的实现

(1)页面
在首页对应的index.js配置页面布局,采用了AntDesign的Layout样式。 中是新闻的展示区,点击

中的标题跳转相应的内容。
index.js

import React,{Component , Fragment} from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import AppHeader from "./components/Header";
import { Layout } from 'antd';
import './style.css'
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import List from './containers/List/'
import Detail from './containers/Detail/'
const { Header, Footer,   Content } = Layout;
class App extends Component{
    render() {
        return(
            <BrowserRouter>
            <Layout style = {{minWidth:1300, height:'100%' }} >
                <Header className = 'header'>
                    <AppHeader/>
                </Header>
                <Content className = 'content'>

                    <Switch>
                        /
                    {/* Switch  匹配一个不会继续匹配   */}
                    <Route path='/detail' component={Detail}/>
                    {/*访问根目录,如果/在前那么detail和根路径也会匹配,/显示出根路径 现在detail在前,如果是根路径和detail匹配不上 */}
                    <Route path = '/:id?' component = {List}/>
                    {/*/id可不传*/}
                    </Switch>

                </Content>
                <Footer className = "footer">@copyright Lux.Lin 2022</Footer>
            {/*    css className*/}
            </Layout>
            </BrowserRouter>
        )
    }
}

ReactDOM.render( <App/>, document.getElementById('root'));


(2)List组件
要在挂载完成后componentDidMount()中请求对应的List接口数据,在页面第一次加载时显示id为1对应的list,这里需要后端的协同使得url后面没有id自动请求id=1的数据。
另:url参数:追加到 URL 上的一个名称/值对。参数以问号 (?) 开始并采用 name=value 的格式。如果存在多个 URL 参数,则参数之间用一个 (&) 符隔开。

    componentDidMount() {
        const id = this.props.match.params.id;
        console.log(id)
        let url = 'http://www.dell-lee.com/react/api/list.json'
        if(id){
            url = url + '?id=' + id
        }
        axios.get(url)
            .then(res => {
                this.setState({
                    data:res.data.data
                })
                console.log(res.data.data)
            })
    }

}

具体点击不同的标题的相关实现是每个Header的每个标题都有一个id对应,请求相应id下的List信息。这里是通过 componentWillReceiveProps(nextProps) 生命周期函数来完成,因为componentDidMount在挂载完成后就不会再执行,而componentWillReceiveProps会在Props发生改变时执行。

    componentWillReceiveProps(nextProps) {
        const id = nextProps.match.params.id;
        axios.get('http://www.dell-lee.com/react/api/list.json?id=' + id)
            .then(res => {
                this.setState({
                    data:res.data.data
                })
                console.log(res.data.data)
            })
    }

那么问题来了 id最初是如何来的?

是在header里从接口获取并在index.js中绑定到即浏览器解析这个地址,list组件接受到这个path里的参数从而拿到的

header 中

     getMenuItems(){
        return this.state.list.map(item =>{
            return (<Menu.Item key={ item.id }   >
                {/*Link需要在Router内部*/}
                <Link to = {`/${item.id}`}>
                    <Icon type = {item.icon} />
                    {item.title}
                </Link>

            </Menu.Item>)
        })

index 中

                    <Switch>
                        /
                    {/* Switch  匹配一个不会继续匹配   */}
                    <Route path='/detail' component={Detail}/>
                    {/*访问根目录,如果/在前那么detail和根路径也会匹配,/显示出根路径 现在detail在前,如果是根路径和detail匹配不上 */}
                    <Route path = '/:id?' component = {List}/>
                    {/*/id可不传*/}
                    </Switch>

当点击一个标题时,当前地址与path = '/:id?'匹配,所以会跳转到List组件,随着把id作为参数传递给List组件,这样完成了组件之间参数的通信。
List

import React, {Component} from 'react';
import { List, Typography, Divider } from 'antd';
import axios from "axios";


class PageList extends Component{
    componentWillReceiveProps(nextProps) {
        console.log(nextProps)
        const id = nextProps.match.params.id;
        axios.get('http://www.dell-lee.com/react/api/list.json?id=' + id)
            .then(res => {
                this.setState({
                    data:res.data.data
                })
                console.log(res.data.data)
            })
    }


    constructor(props) {
        super(props);
        this.state = {
            data :[]
        }
    }

    render() {
        return    <List
            bordered
            dataSource={this.state.data}
            renderItem={item => (
                <List.Item>
                    <Typography.Text mark>[ITEM]</Typography.Text> {item.title}
                </List.Item>
            )}
        />
    }

    componentDidMount() {
        const id = this.props.match.params.id;
        console.log(id)
        let url = 'http://www.dell-lee.com/react/api/list.json'
        if(id){
            url = url + '?id=' + id
        }
        axios.get(url)
            .then(res => {
                this.setState({
                    data:res.data.data
                })
                console.log(res.data.data)
            })
    }

}

export default PageList;

在这里插入图片描述

标签:react,res,day04,间通信,item,import,data,id
来源: https://blog.csdn.net/weixin_46728068/article/details/121344951

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有