React学习笔记

157 阅读5分钟

React路由

//是H5的HistoryApi提供的路由
const history = History.createHashHistory
//是哈希路由,优点:兼容性好,不会造成页面刷新
const history = History.createBrowserHistory

1.路由的基本使用

1.明确好界面中的导航区、展示区
2.导航区的a标签改为Link标签
Demo 3.展示区写Route标签进行路径的匹配 4.的最外侧包裹了一个或

2. BrowserRouter 和 HashRouter

HashRouter地址后面会带一个#,#后面的资源不会发送给服务器

3、路由组件与一般组件

1.写法不同:
    一般组件: <Demo/ >
    路由组件: <Route path=" /demo" component={Demo}/>
2.存放位置不同:
    一般组件:components路由组件: pages
3.接收到的props不同:
    一般组件:写组件标签时传递了什么,就能收到什么
    路由组件:接收到三个固定的属性:
                 history:
                    go: f go(n)
                    goBack: f goBack()
                    goForward: f goForward()
                    push: f push(path, state)
                    replace: f replace(path, state)
                location:
                    pathname: "/about"
                    search: ""
                    state: undefined
                match:
                    params: {}
                    path: "/about"
                    ur1: "/ about"

4.NavLink 与封装NavLink

1.NavLink 可以实现路由链接的高亮,通过 activeclassName 指定样式名
2.标签体内容是一个特殊的标签属性
3.通过 this.props.children 可以获取标签体内容

5.Switch的便用

1.通常情况下,path和lcomponent是一一对应的关系。
2.Switch可以提高路由匹配效率(单一匹配)。

6.解决多级路径刷新页面样式丢失的问题

1.public/index.html 中引入样式时不写./ 写/(常用)
2.public/index.html 中引入样式时不写﹒/写%PUBLIC_URL%(常用)
3.使用HashRouter

7.路由的严格匹配与模糊匹配

1.默认使用的是模柳匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致
2.开启严格匹配:<Route exact={true} path="/about" component={About}/>
3.严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由

8.Redirect的使用

1.一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由2.具体编码:

9.嵌套路由

1.注册子路由时要写上父路由的path2.路由的匹配是按照注册路由的顺序进行的

10.向路由组件传递参数

1.params参数
路由链接(携带参数): <Link to='/demo/test/tom/18'}>详情</Link>
注册路由(声明接收): <Route path="/demo/test/:name/:age" component={Test}/>
接收参数:          const {id,title} = this.props.match.params

11.search参数

路由链接(携带参数):  <Link to='/demo/test?name=tom&age=18'}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:         this.props.location.search 

备注:获取到的 search 是 urlencoded 编码字符串,需要借助 querystring 解析(脚手架已经帮你下载好了直接引用 import qs from querystring)

12.state参数

路由链接(携带参数):
详情 注册路由(无需声明,正常注册即可): 接收参数: this.props.location.state 备注:当前页面(标签页)刷新也可以保留住参数

13.编程式路由导航

借助 this.prosp.history 对象上的API对操作路由跳转、前进、后退
-this.prosp.history.push()
-this.prosp.history.replace()
-this.prosp.history.goBack()
-this.prosp.history.goForward()
-this.prosp.history.go()

深入了解react组件通信

1.setState

深入setState
一、setstate()更新状态的动作是异步还是同步的?----要看setstate的执行位置
    (1).在由react所控制的回调中更新的动作是【异步】的:生命周期勾子、react事件监听回调
    (2).在非react控制的异步回调中更新的动作是【同步】的:定时器回调、原生事件回调
二、setState的两种写法:
(1).对象式写法: setstate( statechange,[callback])
    1.statechange为状态改变对象(该对象可以体现出状态的更改)
    2.callback是可选的回调函数,它在状态更新完毕、界面也更新后(render调用后)才被调用
(2).函数式写法:setstate(updater,[callback])
    1.updater为返回statechange对象的函数。
    2.updater可以接收到state和props。
    3.callback是可选的回调函数,它在状态更新、界面也更新后(render调用后)才被调用。

总结: 1.对象式的settate是函数式的setstate的简写方式(语法糖)2.使用原则: (1).如果新状态不依赖于原状态===>使用对象方式 (2).如果新状态依赖于原状态=-==>使用函数方式 (3).如果需要在setstate()执行后获取最新的状态数据,要在第二个callback函数中读取。

2.React路由组件懒加载

//1.通过React的lazy函数配合import()函数动态加载路由组件===>路由组件代码会被分开打包const Login = lazy(()=>import( 'xxx /xxxx/test ' ))
//2.通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading

<Suspense fallback={

loading...

}>

4.Effect Hook

(1).Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)(2). React中的副作用操作:
        发ajax请求数据获取设置订阅/启动定时器
(3).语法和说明:
    useEffect(() =>{
            //在此可以执行任何带副作用操作return () => { //在组件卸载前执行
            //在此做一些收尾工作,比如清除定时器/取消订阅等
    },[stateValue])//如果指定的是[],回调函数只会在第一次render()后执行
(4).可以把useEffect Hook看做如下三个函数的组合
        componentDidMount()
        componentDidUpdate()
        componentwillUnmount()

5.Context理解

一种组件间通信方式,常用于【祖组件】与【后代组件】间通信使用
1))创建Context容器对象:
    const xxxContext = React.createContext()
    //const { Provider }  = xxxContext
2)渲染子组时,外面包裹 xxxContext.Provider,通过value属性给后代组件传递数据:
    <Provider value = { 数据 }>
            <子组件>
    </Provider>

3)后代组件读取数据:
//如果不写在一个页面中,记得引入从祖组件中暴露 xxxContext 然后在要用的后代组件中引入 
    //第一种方式:仅适用于类组件
    static contextType = xxxContext     //声明接收context 
    const {...} = this.context                        //读取context中的value数据

    //第二种方式:函数组件与类组件都可以
    //在引入的 xxxContext 中解构 Consumer
    const { Consumer } = xxxContext
    <Consumer>
        {
            value =>(  //value就是context中的value数据
            要显示的内容 )
        }
    </Consumer>

6.组件通信方式总结

组件间的关系:
        父子组件
        兄弟组件|(非嵌套组件)
        祖孙组件(跨级组件)
几种通信方式:
    1.props :
         最简单的方式
    2.消息订阅-发布:
        pubs-sub,event等等
    3.集中式管理:
        redux.dva等等
     4.conText:
        生产者-消费者模式
比较好的搭配方式:
        父子组件:props
        兄弟组件:消息订阅-发布、集中式管理
        祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)