美文网首页
React 学习笔记 04 React-Route路由

React 学习笔记 04 React-Route路由

作者: Upcccz | 来源:发表于2019-04-13 19:41 被阅读0次

    fetch

    js原生方法,用来替换XMLHttpRequest的,是基于Promise的,不兼容ie6,但是有一个插件whatwg-fetch来兼容ie(兼容到ie6,是封装XMLHttpRequest,让其有和fetch一样的API)

    // fetch(url,config)
    // 第一个参数 请求路径
    // 第二个参数 请求配置选项:请求方法(默认是GET),请求参数,跨域模式,是否带cookie,请求头,超时时间
    
    fetch('./data.json')
    .then(res=>{ // 不同的是 只要服务器有响应就会触发 不管是成功还是失败
        console.log('响应对象',res) // 不仅仅是响应的数据 还包含了响应头 响应体
    
        // fetch 封装了4个类 Resquest , Response , Header, Body
    
        // Resquest 请求实例 fetch('./data.json')
    
        // Response 响应实例
    
        // Body =>  响应体类,提供了text() , json() ,blob(), arrayBuffer() ,formData()
        // 用来将数据格式化成不同的类型然后返回一个Promise对象
    
        var promise = res.text(); // 以字符串的形式获取响应结果
        promise.then(data=>{
            console.log('响应结果解析成功',data)
        }).catch(err=>{
            console.log('响应结果解析失败',err)
        })
    
    })
    .catch(err=>{ //  类似服务器网络中断这种情况才会触发catch 就是服务器没有任何响应的时候 触发catch
        console.log(err)
    })
    
    
    // 简化写法
    
    fetch('./data.json')
    .then(res=>res.json()) // 这里就是返回的就是上面的那个promise
    .then(data=>{
        console.log('响应结果解析成功',data)
    }).catch(err=>{
        console.log('响应结果解析失败',err)
    })
    
    // 配置选项
    
    fetch('./data.json',{
        mothod: 'post',
        body: 'a=1&b=2'
        headers : {
            'Content-Type': 'application/x-www-form-urlencoded' // 表单类型键值对的请求
            // 文件上传 'multipart/form-data'
        },
        mode:"no-cors", // 设置不支持cors跨域  默认是支持 一般不会设置这个选项
        credentials: 'include' // 默认不发送 'same-origin' 同源才发送 'include'都发送cookie
    })
    

    react-route

    基本使用
    // 安装 4.x版本的 react-route-dom 是包含了核心库 react-route的
    npm i react-route-dom  -S
    
    
    // import { Router }  from 'react-route-dom'
    
    // 这个Router是相当于是VueRouter的,负责包括所有的路由记录
    // 但是本身是抽象的 不能直接使用 因为它不知道该使用哪种模式
    
    // 它拥有四个子类:{BroswerRouter} {HashRouter} {StaticRouter} {MemoryRouter}
    
    // BroswerRouter  对应 history模式
    // HashRouter 对应  hash 模式
    
    import { BrowserRouter as Router, Route } from 'react-router-dom'
    
    
    class App extends React.Component {
        render(){
            return (
                <Router>
                    <div>
                        {/* exact 精准拼配 Router必须有一个根元素*/}
                        <Route exact path="/" component={Home}/>
                        <Route path="/news" render={()=>(<h1>我是一个news组件</h1>)}/>
                    </div>
                </Router>
            )
        }
    }
    
    ReactDOM.render(<App/>,document.getElementById('app'))
    
    
    关于重定向
    
    import { HashRouter as Router,Route,Redirect } from 'react-router-dom'
    
    <Router>
        <div>
            <Route path="/goods" component={Goods}/>
            <Redirect to="/home" from="/" /> {/* /重定向到首页 */}
        </div>
    </Router>
    
    
    <Route exact path="/" render={() => (
      loggedIn ? (<Redirect to="/dashboard"/>) : (<PublicHomePage/>)
    )}/>
    
    
    <Redirect
      to={{
        pathname: "/login",
        search: "?utm=your+face",
        state: { referrer: currentLocation }
      }}
    />
    
    <Redirect push to="/somewhere/else" />
    // push 是一个bool值,使用push 而不是replace
    
    关于Link 和 NavLink
    import { HashRouter as Router,Route,Link, NavLink} from 'react-router-dom'
     
    <Router>
        <div>
            {/* Link标签本质还是a便签 */}
            <Link to="/home">首页</Link>
            <Link to="/goods">商品</Link>
            <hr/>
    
            {/* 与route-link 差不多 会给激活的NavLink 添加一个active类 */}
            <NavLink to="/home">首页</NavLink>
            <hr/>
    
             {/* 可以使用activeClassName自定义这个类名 一把使用第三方样式的时候使用 */}
            <NavLink to="/home" activeClassName='myActive'>首页</NavLink>
            <hr/>
    
             {/* 也要加exact精准匹配 不然active类会在跳转到/home的时候 在两个NavLink标签上都加上 */}
            <NavLink to="/" exact >Index</NavLink>
            <NavLink to="/home">首页</NavLink>
            <hr/>
    
            <Route path="/goods" component={Goods}/>
            {/* /重定向到首页 */}
            <Redirect to="/home" from="/" /> 
        </div>
    </Router>
    
    关于Switch组件

    Switch组件让路由在匹配到第一个组件时就结束匹配

    import { HashRouter as Router,Route,Switch} from 'react-router-dom'
    
    <Router>
        <div>
            {/*Switch一定要加 不然有多少个路由 每次跳转的时候就会匹配多少次 影响性能*/}
            <Switch>
                {/*在Switch中 如果默认路径不加 exact 不管跳转哪里都会跳转到Index 因为'/xxx'都会匹配到'/' */}
    
                {/* exact是bool值 可以设置为false。exact={false} 实现的是 url.pathname === Route的path属性 */}
    
                <Route exact path="/" component={Index}/>
                <Route path="/home" component={Home}/>
                <Route path="/goods" component={Goods}/>
            </Switch>
        </div>
    </Router>
    
    
    嵌套路由
    class App extends React.Component {
        render(){
            return (
                <Router>
                    <Route path="/home" component={Home}/>
                    <Route path="/goods" component={Goods}/>
                </Router>
            )
        }
    }
    
    class Goods extends React.Component {
        render(){
            return (
                <Router>
                    {/* 必须要连接/goods 不然无法匹配 因为每次匹配都是从最外层开始 */}
                    {/* /goods 一定不能设置 exact 不然/goods/phone根本就匹配不到路由/goods 那Goods组件都不会渲染 更不会有子路由组件渲染的机会*/}
                    <Route path="/goods/phone" component={Phone}/>
                    <Route path="/goods/food" component={Food}/>
                </Router>
            )
        }
    }
    
    动态路由
    class App extends React.Component {
        render(){
            return (
                <Router>
                    <Route path="/home" component={Home}/>
                    <Route path="/:myPath" component={Product}/>
                </Router>
            )
        }
    }
    
    class Product extends React.Component {
        render(){
            return (
                <Router>
                    {/* 必须要连接/goods 不然无法匹配 因为每次匹配都是从最外层开始 */}
                    {/* /goods 一定不能设置 exact 不然/goods/phone根本就匹配不到路由/goods 那Goods组件都不会渲染 更不会有子路由组件渲染的机会*/}
                    <Route path="/phone" component={Phone}/>
                    <Route path="/food" component={Food}/>
                </Router>
            )
        }
    
        componentDidMount(){ // 一般在这个钩子中请求数据 渲染视图
            console.log(this.props)
            // 动态路由的props上有三个属性 history location match
    
            // history 历史对象== this.ptops.history.push() /  this.ptops.history.replace() / goBack / go
            // 编程式跳转
    
            // location 当前地址信息对象 = 当前路由的hash pathname search(?a=1&b=2) state 
    
            // match 匹配对象 拥有isExact params(myPath:phone)  path(/:myPath) url(/phone) 
            // 相当于this.$route.params.myPath
        }
    }
    
    

    为什么要在componentDidMount中获取数据:更新期4个钩子不能调用setState 所有创建周期的render不行,然后componentWillMount会被执行两次

    动态路由需要在componentWillReceiveProps获取数据,因为动态路由使用同一个组件,组件的componentDidMount只会执行一次

    相关文章

      网友评论

          本文标题:React 学习笔记 04 React-Route路由

          本文链接:https://www.haomeiwen.com/subject/tkmkwqtx.html