美文网首页
React问题记录

React问题记录

作者: 小姑凉喜欢无脸男 | 来源:发表于2019-03-25 16:48 被阅读0次
    1. npx creact-react-app 出来没有webpack文件

    用npm run eject命令。
    react-scripts 是 create-react-app 的一个核心包,一些脚本和工具的默认配置都集成在里面,而命令执行后会将封装在 create-react-app 中的配置全部反编译到当前项目,这样就能完全取得 webpack 文件的控制权。但该操作时不可逆的,所以如果想回去,只有重新npm creat-xxxx。
    执行npm run eject命令可能会出现一个报错:如下


    error.png

    解决方法:
    git init
    git add .
    git commit -m 'init'

    2.路由跳转传参方式
    在跳转路由的链接中通过‘?’传递参数
    <Switch>
        <Route exact path="/" component={Home} />
        <Route exact path="/about" component={About} />
    </Switch>
    //link方式跳转
    <Link to="/about?msg='url参数'">去关于我的页面 url传递参数</Link>
    //js方式跳转
     this.props.history.push({ pathname:"/about?msg='url参数'"});
    //about中获取参数
    console.log(this.props.location)
    //{pathname: "/about", search: "?msg='url参数'", hash: "", state: undefined}
    
    

    优缺点:参数比较灵活,参数直接在url中暴露,刷新路由页面时传递参数依然可以正常访问。缺点是还需要js通过search中解析类似getParameter(msg)方式获取真实值

    通过:id方式
    <Route exact path="/about/:msg" component={About} />
    //link方式
    <Link to="/about/url参数">去关于我的页面 路由配置传递参数</Link>
    //js方式跳转
     this.props.history.push({ pathname:"/about/'url参数'"});
    //about中获取参数
    console.log(this.props.match.params.msg)
    //url参数
    

    优缺点:参数比较灵活,参数直接在url中暴露,刷新路由页面时传递参数依然可以正常访问。但每增加一个参数需要在Route中注册一个,而且顺序需要一致。

    其他query(自定义属性)和state
    // query 传递参数
    this.props.history.push({
        pathname: '/about',
        query: {
            msg: 'msg by query'
        }
    });
    // state 传递参数
    this.props.history.push({
        pathname: '/about',
        state: {
            msg: 'msg by state'
        }
    });
    
    // query 接受参数
    console.log(this.props.location.query.msg)//msg by query
    // state 接受参数
    console.log(this.props.location.state.msg)//msg by state
    

    优缺点:参数灵活,不用给Route额外的配置,参数是加密的,不暴露在url上。

    3. React-router V4 中的BrowserRouter和HashRouter
    HashRouter

    它使用URL的哈希部分(即window.location.hash)来保持页面的UI与URL同步。
    重要说明:哈希历史记录不支持location.key或location.state。

    BrowserRouter

    使用HTML5历史API( pushState,replaceState和popstate事件),让页面的UI同步与URL

    可以查看官网api了解更多。
    区别:1.URL的不同
    HashRouter使用URL(即window.location.hash)的哈希部分来保持UI与URL同步的。哈希历史记录不支持location.key和location.state 详情查看history 用来支持旧版浏览器,官方不建议使用。简单来说,就是不需要服务器端渲染,靠浏览器的# 来区分path。
    BrowserRouter使用HTML5 history API,保证UI界面和URL保存同步。要求服务器端对不同URL返回不同的HTML。

    例如,有两个页面Home和About,如果用HashRouter,两个URL就是这样,因为#后面的部分不会发给服务器,所以服务器只需要应对 / 路径的请求就好

    https://xxxxxx.com/#/home
    https://xxxx.com/#/about
    

    如果用BrowserRouter,两个URL就是这样,服务器不得不对 /home 和 /about 做不同请求

    https://xxxxxx.com/home
    https://xxxx.com/about
    

    2.路由跳转传递参数和刷新页面数据丢失
    当点击触发js跳转到about,然后回退到上一页,再点击下一页到about页面。参数通过state传递

    //about组件
    class About extends Component {
        constructor(props) {
            super(props);
        }
        render() {
            console.log(this.props.location);
            return (
                <div className="demo">
                    我是一个路由跳转后的子页面
                    <br />
                    <div>
                        参数:{JSON.stringify(this.props.location)}
                    </div>
                    <Link to="/">回首页</Link>
                </div>
            );
        }
    }
    //通过js跳转
    this.props.history.push({
        pathname: '/about',
        state: {
            msg: 'msg by state'
        }
    });
    //HashRouter结果
    //第一次进入页面打印结果
    {"pathname":"/about","state":{"msg":"msg by state"},"search":"","hash":""}
    //刷新页面或者后退再前进
    {"pathname":"/about","search":"","hash":""}
    
    //BowserRouter结果
    //第一次进入页面打印结果
    {"pathname":"/about","state":{"msg":"msg by state"},"search":"","hash":"","key":"1m6gz4"}
    //刷新页面或者后退再前进
    {"pathname":"/about","state":{"msg":"msg by state"},"search":"","hash":"","key":"1m6gz4"}
    

    当我们通过state传递参数的时候,因为hashRouter没有使用html5中history的api,无法从历史记录中获取到key和state值,所以当刷新路由后state值会丢失导致页面显示异常。

    总结:实现路由页面页面刷新数据不丢失的方案
    BorwserRouter有三种方式(url传值,路由参数传值,以及state)
    HashRouter有两种方式(url传值,路由参数传值)
    本地缓存或者状态管理方案

    4. 生命周期
    import React, { Component } from 'react';
    
    import './App.css';
    
    class App extends Component {
      constructor (props){
        super(props)
        this.state = {
          data: 'old state'
        }
        console.log('c初始化数据constructor')
      }
      //组件将要加载执行
      componentWillMount () {
        console.log('componentWillMount')
      }
      //组件挂载(加载)完成
      componentDidMount () {
        console.log('componentDidMount')
      }
      //将要接受父组件传来的props
      componentWillReceiveProps () {
        console.log('componentWillReceiveProps')
      }
      //子组件是否更新
      shouldComponentUpdate () {
        console.log('shouldComponentUpdate')
        return true
      }
      //组件将要更新
      componentWillUpdate () {
        console.log('componentWillUpdate')
      }
      //组件更新完成
      componentDidUpdate () {
        console.log('componentDidUpdate')
      }
    //组件即将销毁
      componentWillUnmount () {
        console.log('componentWillUnmount')
      }
      //处理点击事件
      handelClick(){
        console.log('更新数据')
        this.setState({
          data:'new state'
        })
      }
      render() {
        console.log('render')
        return (
          <div>
            <div>app</div>
            <button onClick={()=>{this.handelClick()}}>更新组件</button>
          </div>
          
    
        );
      }
    }
    
    export default App;
    
    打印.png
    5.@withRouter

    withRouter可以包装任何自定义组件,将react-router 的 history,location,match 三个对象传入。
    使用@需要install 两个依赖,并在package.json的babel中配置


    下载依赖与配置.png
    6.react定义组件的三种方式和区别
    1. 函数式定义的无状态组件
    2. es5原生方式React.createClass定义的组件
    3. es6形式的extends React.Component定义的组件
      参考https://www.cnblogs.com/wonyun/p/5930333.html
      补充:无状态函数式组件写法
     const HelloWorld = (props) => (
       <h1>{props.text}</h1>
     )
    

    7. react状态管理Mobx vs Redux

    参考:https://blog.csdn.net/vhwfr2u02q/article/details/79395072

    相关文章

      网友评论

          本文标题:React问题记录

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