React_day04_react routing, communication between components, news website construction

1. Issues related to version compatibility

It was another pit mining process that was inconsistent with the tutorial version, and it also wasted a lot of twists and turns.
In actual development, React17, react DOM router 6. X, antd 4.x
Tutorial version React16, react DOM router 5. X, antd 3.x
At first, I wanted to install a new version to solve the bug a little bit, but it took too much time. Finally, I chose to reduce the version. After modifying the relevant version number in package.json, restart npm install in terminal
Or summarize the relevant pit
(1) Routing related compatibility issues
react-dom-router 5.x -> 6.x
The first error report needs to wrap the route with routes

//5.x
            <BrowserRouter>
                <div>
                    {/*list There are parameters in the back, which will be put in the 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>

Next, corresponding to canceling the component, the parameter cannot be obtained from props

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

                     <Route path = "/newButton" component = {NewButton}/>
------------------------------------------------------------------------
class Newlist extends Component{
    render() {
    //Get the match parameter and url parameter in props
        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 routing

Routing configuration of react router DOM 5. X:
(1) import related packages

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

(2) Configure the path attribute in the component
If the current path matches, it will jump to the corresponding component of the path
In addition, note that the root directory should be placed later,
Other paths such as / detail will also match with / and cause errors if they are at the top of several paths

                <Content className = 'content'>

                    <Switch>
                        /
                    {/* Switch  Matching one will not continue   */}
                    <Route path='/detail' component={Detail}/>
                    {/*Access the root directory. If / is in front, the detail and root path will also match, / shows that the root path is now in front of detail. If the root path and detail do not match */}
                    <Route path = '/:id?' component = {List}/>
                    {/*/id No*/}
                    </Switch>

                </Content>

(3) Click the button to display the corresponding components (list, page, etc.)
In the navigation bar component above the news website, a button for each title is bound
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 It needs to be inside the 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;

Home page rendering

3. Realization of news website

(1) Page
Configure the page Layout in the index.js corresponding to the home page, using the Layout style of ant design. Is the news display area, click

The title in jumps to the corresponding content.
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  Matching one will not continue   */}
                    <Route path='/detail' component={Detail}/>
                    {/*Access the root directory. If / is in front, the detail and root path will also match, / shows that the root path is now in front of detail. If the root path and detail do not match */}
                    <Route path = '/:id?' component = {List}/>
                    {/*/id No*/}
                    </Switch>

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

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


(2) List component
To request the corresponding list interface data in componentDidMount() after the mounting is completed, the list corresponding to ID 1 is displayed when the page is loaded for the first time. Here, the back-end cooperation is required so that there is no ID behind the url, and the data with id=1 is automatically requested.
Another: URL parameter: a name / value pair appended to the URL. The parameter starts with a question mark (?) and takes the form of name=value. If there are multiple URL parameters, the parameters are separated by a (&).

    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)
            })
    }

}

Specifically, click the relevant implementation of different headers. Each Header has an id corresponding to each Header, and request the List information under the corresponding id. This is done through the componentWillReceiveProps(nextProps) life cycle function, because componentDidMount will not be executed after the mount is completed, and componentWillReceiveProps will be executed when the Props are changed.

    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)
            })
    }

So the question is, how did id come in the first place?

It is obtained from the interface in the header and bound to in index.js, that is, the browser parses the address, and the list component receives the parameters in the path

In header

     getMenuItems(){
        return this.state.list.map(item =>{
            return (<Menu.Item key={ item.id }   >
                {/*Link It needs to be inside the Router*/}
                <Link to = {`/${item.id}`}>
                    <Icon type = {item.icon} />
                    {item.title}
                </Link>

            </Menu.Item>)
        })

In index

                    <Switch>
                        /
                    {/* Switch  Matching one will not continue   */}
                    <Route path='/detail' component={Detail}/>
                    {/*Access the root directory. If / is in front, the detail and root path will also match, / shows that the root path is now in front of detail. If the root path and detail do not match */}
                    <Route path = '/:id?' component = {List}/>
                    {/*/id No*/}
                    </Switch>

When a title is clicked, the current address and path = '/:id?' Match, so it will jump to the List component. With the id passed to the List component as a parameter, the communication of parameters between components is completed.
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;

Keywords: Javascript React Algorithm Mini Program

Added by naboth_abaho on Wed, 17 Nov 2021 11:12:34 +0200