码迷,mamicode.com
首页 > 其他好文 > 详细

React框架进阶-setState、ref、路由

时间:2021-02-01 13:00:06      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:ports   render   端口   方式   参数   class   完成   就是   efs   

一、setState进阶

1.setState是一个异步函数

在执行this.setState时,后续的代码会马上执行

state = {
    num:100
}
numChange(){
    var num = this.state.num;
    this.setState({
        num:++num
    });
    console.log(this.state.num)//此时获取到的数据不是最新的
}
render() {
    return (
        <div>
            <h1>index组件</h1>
            <h2>num:{ this.state.num }</h2>
            <button onClick={ ()=>this.numChange() }>增加</button>
        </div>
    )
}

解决办法:

setState可以接收第二个参数,这个参数就是回调函数

回调函数,就是在执行完某个操作后,自动调用的函数

this.setState({ num:++num },()=>{
    console.log(this.state.num)
});

2.state和props混用

state 状态机,定义组件初始数据

props 接收父组件传递过来的数据

父子组件上都有挂载完成钩子函数,在函数都通过setState来修改数据,由于子组件挂载完成后父组件才算挂载完成,会产生一个数据不一致的问题。

解决方法:

setState的第一个参数使用函数,这个函数中可以接收两个参数

第一个参数是组件自己的数据,第二个参数父组件传递过来的最新数据

总结:

setState 作用:会把指定数据与原有的数据进行合并,并重新渲染页面

如果要在执行setState后获取到最新的数据时,需要使用第二个参数(回调函数)

如果组件中把state和props混用时,建议在setState中使用函数

示例代码:

父组件:

import React, { Component } from ‘react‘
import Child from ‘./Child‘
export default class Index extends Component {
    state = {
        num:100
    }
    componentDidMount(){
        // console.log(‘父组件挂载完成...‘)
        this.setState({
            num:200
        })
    }
    numChange(){
        var num = this.state.num;
        this.setState({ num:++num },()=>{
            console.log(this.state.num)//在回调函数中可以获取到最新的数据
        });
        // console.log(this.state.num)//这里获取到的数据不是最新的
    }
    render() {
        return (
            <div>
                <h1>index组件</h1>
                <h2>num:{ this.state.num }</h2>
                <button onClick={ ()=>this.numChange() }>增加</button>
                <hr/>
                <Child indexnum={ this.state.num }></Child>
            </div>
        )
    }
}

子组件:

import React, { Component } from ‘react‘
export default class Child extends Component {
    state = { num:50 }
    componentDidMount(){
        // console.log(‘子组件挂载完成...‘)
        // this.setState({
        //     num:this.props.indexnum
        // })
        // setState如果第一个参数是函数的话
        // 第一个参数是组件自己的数据,第二个参数父组件传递过来的最新数据
        this.setState(function(state,props){
            state.num = props.indexnum;
        })
    }
    render() {
        return (
            <div>
                <h2>child组件</h2>
                <h2>num:{ this.state.num }</h2>
            </div>
        )
    }
}

二、DOM操作-ref

1.字符串

<h2 ref="myh2">num:{ this.state.num }</h2>

在组件挂载完成的钩子函数中对它进行操作

componentDidMount(){
    this.refs.myh2.innerHTML = ‘hello ref‘
}

refs在react中已被弃用

2.回调函数

<Child ref={(ev)=>this.setChild(ev)}></Child>

在自定义方法中对子组件进行数据的修改

setChild(el){
    //el 现在就是子组件本身
    if(el){
        el.setState({
            num:300
        })
    }
}

3.createRef

在构造函数中使用React.createRef方法,在React推荐使用这种方式,因为回调函数的方式会自动的触发。

constructor(){
    super();
    this.childEl = React.createRef();
}

在子组件上添加ref属性

<Child ref={ this.childEl }></Child>

在父组件的挂载完成钩子函数中,就可以直接修改的数据或者调用子组件的方法

componentDidMount(){
    this.childEl.current.setState({
        num:200
    })
}

三、代理配置和网络请求

1.代理配置

(1)改变React默认运行端口

①在启动react项目时,选择更换端口

②修改文件

node_moudles/react-scripts/scripts/state.js第64行

const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 5000;

③package.json中设置端口

"scripts": {
    "start": "set PORT=3333 && react-scripts start",
    ...

(2)设置代理转发规则

package.json中设置

"proxy":"http://localhost:3000"

==proxy==是一个一级配置选项

(3)通过插件http-proxy-middleware实现代理转发设置

在package.json中进行设置代理规则,只要不是路由规则的请求地址都会进行代理转发,所以为了更加准确的给指定的请求进行代理转发,需要使用插件来实现。

先把package.json中的proxy选项删除

①安装插件

npm i http-proxy-middleware --save

②在src目录下,创建一个文件,文件名叫:setupProxy.js,并配置转发规则

const proxy = require(‘http-proxy-middleware‘)
module.exports = function(app){
    app.use(proxy.createProxyMiddleware(‘/api‘,{
        target:‘http://localhost:3000‘
    }))
}

③重启项目

2.fetch

fetch(‘/api/getcate‘).then(response=>response.json()).then(res=>{
	console.log(res)
})

3.axios

npm i axios
import axios from ‘axios‘
axios.get(‘/api/getcate‘).then(res=>{...})

四、路由

1.安装

npm i react-router-dom --save

2.引入

src/index.js 引入路由模式组件

BrowserRouter是history模式

HashRouter是hash模式

import { BrowserRouter } from ‘react-router-dom‘
import App from ‘./App‘
ReactDOM.render(<BrowserRouter><App/></BrowserRouter>,document.getElementById("root"));

3.基本使用

(1)先创建几个页面组件

(2)在src/App.js根组件中引入路由出口和路由规则组件,并定义路由规则

import { Switch,Route } from ‘react-router-dom‘
import Index from ‘./components/pages/Index‘
import Login from ‘./components/pages/Login‘
function App() {
    return (
        <div className="App">
            <Switch>
                <Route path="/index" component={ Index }></Route>
                <Route path="/login" component={ Login }></Route>
            </Switch>
        </div>
    );
}
export default App;

Switch是路由出口,作用和vue中router-view相同

Route是具体的一个路由规则,需要设置path属性和component属性

4.重定向

import { Switch,Route,Redirect } from ‘react-router-dom‘


<Switch>
	<Route path="/index" component={ Index }></Route>
    <Route path="/login" component={ Login }></Route>
	<Redirect path="*" to="/index"></Redirect>
</Switch>

5.路由导航

(1)内置组件

Link、NavLink

他们两个都会在页面上生成a标签,都需要设置to属性

NavLink会根据当前访问的路由规则给指定的组件设置激活状态的类名

示例代码:

引入需要的组件

import { Switch,Route,Redirect,Link,NavLink } from ‘react-router-dom‘

使用

<Link to="/index">首页</Link>
<Link to="/login">登录页</Link>
<hr/>
<NavLink to="/index">首页</NavLink>
<NavLink to="/login">登录页</NavLink>

(2)编程式导航

只要使用了路由,由路由渲染出来的页面组件的props中包含了路由相关属性和方法

this.props.history.push

this.props.history.replace

this.props.history.go(-1)

this.props.history.goBack()

6.路由嵌套

如果某个页面需要展示出来不同的子级页面,那么就在这个页面中继续引入Switch和Route,定义 好路由出口和路由规则,就可以不子级页面内容展示路由出口的位置。

React框架进阶-setState、ref、路由

标签:ports   render   端口   方式   参数   class   完成   就是   efs   

原文地址:https://www.cnblogs.com/hxmw/p/14353689.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!