• React学习笔记


    参考网站:http://jspang.com/2017/08/15/react_basic/

    1、React起源于Facebook的内部项目

          ReactJS官方地址:https://facebook.github.io/react/

          GitHub地址:https://github.com/facebook/react

    react特点:

          虚拟DOM:React是以数据驱动的,每次数据变化React都会扫码整个虚拟DOM树,自动计算与上次虚拟DOM的差异变化,然后针对需要变化的部分进行实际的浏览器DOM更新

          组件化:React可以从功能角度横向划分,将UI分解成不同组件,各组件都独立封装,整个UI是由一个个小组件构成的一个大组件,每个组件只关系自身的逻辑,彼此独立

         单向数据流:Reac设计者认为数据双向绑定虽然便捷,但在复杂场景下副作用也是很明显,所以React更倾向于单向的数据流动--从父节点传递到子节点。(使用ReactLink也可以实现双向绑定,但不建议使用)

    2、react.js和react-dom.js文件

         react.js:实现React核心逻辑,且与具体的渲染引擎无关,从而可以跨平台共用。如果应用要迁移到React Native,这一部分逻辑是不需要改变的。

         react-dom.js:包含了具体的DOM渲染更新逻辑,以及服务端渲染的逻辑,这部分就是与浏览器相关的部分

    3、React.createElement( string/ReactClass type,[object props], [children ...])   返回一个给定类型的ReactElement元素

         type:必须,可以是html标签名称字符串,也是可以是ReactClass

         [object props]:可选,该标签的属性,一般为null

         [children ...]:可选,该元素的子节点   

         链接:http://www.onmpw.com/tm/xwzj/web_103.html

     4、JSX的好处:

          可以使用熟悉的语法仿照HTML来定义虚拟DOM

          与javaScript之间等价交换,代码更加直观

    5、getInitialState函数是用来设置state里面值的默认值的

         必须有返回值return

    1 getInitialState: function () {
    2    return {enable: false}
    3 }

         getDefaultProps函数是用来设置state里面值的默认值的

     6、props与state的区别

          props不能被其所在的组件修改,从父组件传递进来的属性不会在组件内部更改;state只能在所在组件内部更改,或在外部调用setState函数对状态进行间接修改。

     7、render成员函数

          首先说render是一个函数,它对于组件来说,render成员函数是必需的。render函数的主要流程是检测this.props和this.state,再返回一个单一组件实例。

          render函数应该是纯粹的,也就是说,在render函数内不应该修改组件state,不读写DOM信息,也不与浏览器交互。如果需要交互,应该在生命周期中进行交互。

    8、react的表单--bind复用

         bind方法为事件相应函数增加一个参数,事件响应函数通过该参数识别事件源

         bind可以点击这里:http://www.cnblogs.com/zhaobao1830/p/8016638.html 

        

     1 <!DOCTYPE html>
     2 <html lang="zh">
     3 <head>
     4   <meta charset="UTF-8">
     5   <meta http-equiv="x-ua-compatible" content="ie=edge">
     6   <title>表单--bind复用</title>
     7   <meta name="viewport" content="width=device-width, initial-scale=1,minimum-scale=1,maximum-sacle=1,user-scalable=no">
     8   <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
     9   <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    10   <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
    11 </head>
    12 <body>
    13   <div id="demo"></div>
    14   <script type="text/babel">
    15     var MyForm = React.createClass({
    16       getInitialState: function() {
    17         return{
    18           username: '',
    19           gender: 'man',
    20           checked: true
    21         }
    22       },
    23       handleChange: function (name, event) {
    24         var newState = {}
    25         newState[name] = name === 'checked' ? event.target.checked : event.target.value
    26         this.setState(newState)
    27         console.log(newState)
    28       },
    29       handleSubmit: function (e) {
    30         e.preventDefault()
    31         var is = this.state.checked ? '' : '不是'
    32         var gender = this.state.gender === 'man' ? '帅哥' : '美女'
    33         alert(this.state.username+ is + gender +'.' );
    34       },
    35       render: function () {
    36         return (
    37             <form onSubmit={this.handleSubmit}>
    38               <label htmlFor="username">请输入您的名字:</label>
    39               <input type="text" name="username" id="username" onChange={this.handleChange.bind(this, "username")} value={this.state.username}/>
    40               <br/>
    41               <label htmlFor="checkBox">是或否:</label>
    42               <input type="checkbox" value="是否" name="checked" id="checkBox" onChange={this.handleChange.bind(this, "checked")} checked={this.state.checked}/>
    43               <br/>
    44               <label htmlFor="username">请选择</label>
    45               <select name="gender" onChange={this.handleChange.bind(this, "gender")} value={this.state.gender}>
    46                 <option value="man">帅哥</option>
    47                 <option value="woman">美女</option>
    48               </select>
    49               <br/>
    50               <button type="submit">提交</button>
    51             </form>
    52         )
    53       }
    54     })
    55     ReactDOM.render(
    56       <MyForm/>,
    57       document.getElementById("demo")
    58     )
    59   </script>
    60 </body>
    61 </html>

    这个里面的bind,this是绑定到当前环境下,第二个参数是预设一个参数,对应的是handleChange()里的name参数

    9、react表单--name复用

       name复用方式直接读取表单的属性值,比bind写法少一个参数(React中事件响应函数会自动绑定this)。其原理是在所有的标签中设置统一的name属性,并将这个属性值对应为state属性,在事件响应函数中通过读取表单的name值获得state属性,从event.target.value获取用户输入的值(check控件稍有不同),要求所有相关的标签(包括input标签)都要统一设置name属性。

    就是每个标签加一个name,然后判断name来进行state的更改。但是我不建议这样使用,因为为每个标签增加一个name属性值并不友好。

     1 <!DOCTYPE html>
     2 <html lang="zh">
     3 <head>
     4   <meta charset="UTF-8">
     5   <meta http-equiv="x-ua-compatible" content="ie=edge">
     6   <title>表单--name复用</title>
     7   <meta name="viewport" content="width=device-width, initial-scale=1,minimum-scale=1,maximum-sacle=1,user-scalable=no">
     8   <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
     9   <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    10   <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
    11 </head>
    12 <body>
    13   <div id="demo"></div>
    14   <script type="text/babel">
    15     var MyForm = React.createClass({
    16       getInitialState: function() {
    17         return{
    18           username: '',
    19           gender: 'man',
    20           checked: true
    21         }
    22       },
    23       handleChange: function (event) {
    24         var newState = {}
    25         newState[event.target.name] = event.target.name === 'checked' ? event.target.checked : event.target.value
    26         this.setState(newState)
    27         console.log(newState)
    28       },
    29       handleSubmit: function (e) {
    30         e.preventDefault()
    31         var is = this.state.checked ? '' : '不是'
    32         var gender = this.state.gender === 'man' ? '帅哥' : '美女'
    33         alert(this.state.username+ is + gender +'.' );
    34       },
    35       render: function () {
    36         return (
    37             <form onSubmit={this.handleSubmit}>
    38               <label htmlFor="username">请输入您的名字:</label>
    39               <input type="text" name="username" id="username" onChange={this.handleChange} value={this.state.username}/>
    40               <br/>
    41               <label htmlFor="checkBox">是或否:</label>
    42               <input type="checkbox" value="是否" name="checked" id="checkBox" onChange={this.handleChange} checked={this.state.checked}/>
    43               <br/>
    44               <label htmlFor="username">请选择</label>
    45               <select name="gender" onChange={this.handleChange} value={this.state.gender}>
    46                 <option value="man">帅哥</option>
    47                 <option value="woman">美女</option>
    48               </select>
    49               <br/>
    50               <button type="submit">提交</button>
    51             </form>
    52         )
    53       }
    54     })
    55     ReactDOM.render(
    56       <MyForm/>,
    57       document.getElementById("demo")
    58     )
    59   </script>
    60 </body>
    61 </html>

     10、在react里面,input标签有点特殊

            将Input中的value绑定到state的React组件是可控组件,反之则是不可控组件

            在render()函数中设置了value的<Input>是一个功能受限的组件,渲染出来的HTML元素始终保存value属性的值,即使用户输入也不会改变     

    1 var  MyForm = React.createClass({
    2     render:function(){
    3         return(
    4             <div>
    5             <input type="text" value="zb" />
    6             </div>
    7         )
    8     }
    9 });

          这时打开浏览器,value值无法改变,也无法删除,这时由React的渲染策略决定的

    11、可控组件

          

     1 <!DOCTYPE html>
     2 <html lang="zh">
     3 <head>
     4   <meta charset="UTF-8">
     5   <meta http-equiv="x-ua-compatible" content="ie=edge">
     6   <title>Title</title>
     7   <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
     8   <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
     9   <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
    10 </head>
    11 <body>
    12    <div id="demo"></div>
    13    <script type="text/babel">
    14      var MyForm = React.createClass({
    15        getInitialState: function () {
    16          return {value: 'zb'}
    17        },
    18        handleChange: function (event) {
    19          this.setState({value: event.target.value})
    20        },
    21        render: function () {
    22          return (
    23            <div>
    24              <input type="text" value={this.state.value} onChange={this.handleChange}/>
    25            </div>
    26          )
    27        }
    28      });
    29      ReactDOM.render(
    30        <MyForm/>,
    31        document.getElementById('demo')
    32      )
    33    </script>
    34 </body>
    35 </html>

     在条件允许的情况下,我们应该优先考虑编写可控组件

     可控组件的特点:

       1、符合React单向数据流特性,即从state流向render输出的结果

       2、数据存储在state中,便于访问和处理

    12、快速构建react开发环境的脚手架工具:create-react-app

           地址:https://github.com/facebookincubator/create-react-app

           create-react-app优点:

              无需配置:官方的配置堪称完美,几乎不用你再配置任何东西,就可以上手开发项目

              高集成性:集成了对React、JSX、ES6和Flow的支持

              自带服务:集成了开发服务器,你可以实现开发预览一体化

              热更新:保存自动更新

              全兼容性:自动处理css的兼容问题,无需添加-webkit前缀

              自动发布:集成好了发布成品功能,编译后直接发布,并且包含了sourcemaps功能 

    13、构建工具:generator-react-webpack

            参考地址:http://jspang.com/2017/10/22/react-all-01/

           它是需要yeoman的支持的

           优点:

                  基于webpack构建,可以很容易的配置自己需要的webpack

                  支持ES6,集成了Bable-Loader

                  支持不同风格的CSS(sass,less,stylue)

                  支持PostCSS转换样式

                  集成了esLint功能

                 可以轻松配置单元测试,比如Karma和Mocha

    14、React路由需要用到俩个模块:Router(路由器)和Route(路由)

           exact是精确匹配的意思

           React会匹配所有能匹配的路由组阶,exact可以使我们的匹配更精确。exact的值为bool型,为true是表示严格匹配,为false时为正常匹配

    1  <Route  path="/" component={Jspang} />
    2  <Route  path="/Jspangb" component={Jspangb} />
    3  //这种情况下,输入路由"/Jspangb",会把Jspang组件也展示出来
    4 
    5 //所以我们经常使用exact来解决这个问题。
    6 <Route  exact  path="/"  component={Jspang} />
    7 <Route  path="/Jspangb" component={Jspangb} />

             作为一个链接是用激活状态的,激活状态就是当我们处在这个链接时。activeClassName就是设置激活状态的样式,它接受一个类名

    1 .active{
    2   color: red
    3 }
    4 <NavLink to='/Jspangc' activeClassName='active'>Jspangc</NavLink>

    15、404页面,需要用到Switch组件

           地址:http://jspang.com/2017/10/22/react-all-01/#03webpack01       

           Redirect组件使用 

           有时候我们开发中希望在程序中根据业务逻辑进行跳转,或者一个链接点击后直接跳转到其它链接。这时候可以使用Redirect组件解决。

     16、路由:Router中属性和路由模式 

            basename属性

            basename的作用是个我们增加一级导航目录,比如以前的导航目录是:http://localhost:1717/Jspangb  现在想访问同一个页面,但是路径变成http://localhost:1717/demo/Jspangb。这时候就可以使用basename属性来设置。basename属性是放在<router>标签里边的。     

     1  <Router basename="demo">
     2         <div>
     3          <Nav/>
     4             <Switch>
     5                 <Route  exact  path="/"  component={Jspang} />
     6                 <Route  path="/Jspangb" component={Jspangb} />
     7                 <Route  path="/Jspangc/:param" component={Jspangc} />
     8                 <Redirect from="/redirect" to="/Jspangb" />
     9                 <Route  component={Error} />
    10             </Switch>
    11             
    12         </div>
    13     </Router>,

              forceRefresh属性

             这个属性的作用是开启或者关闭React Router,也就是说如果你把forceRefresh的值设置成真,它将关闭React路由系统,而真实的去服务器端请求信息。

             现在我们把forceRefresh设置成true,你会发现路由已经不能使用了。          

     1 <Router basename="demo" forceRefresh={true}>
     2     <div>
     3         <Nav/>
     4         <Switch>
     5             <Route  exact  path="/"  component={Jspang} />
     6             <Route  path="/Jspangb" component={Jspangb} />
     7             <Route  path="/Jspangc/:param" component={Jspangc} />
     8             <Redirect from="/redirect" to="/Jspangb" />
     9             <Route  component={Error} />
    10         </Switch>
    11         
    12     </div>
    13 </Router>,

               这个操作经常使用在大型项目,在服务器跳转和ReactRouter切换时使用。比如作一个APP活动页面,第一次请求时我们到服务器端请求整个页面,然后请求后,整个页面DOM进行本地缓存,生成React Router实现本地单页应用。 只要设置我们的forceRefresh就可以了。   

           5种路由方式

            我们一直在使用的路由方式是BrowserRouter,也就是浏览器的路由方式,其实React还有几种路由方式:          

    1. BrowserRouter:浏览器的路由方式,也是我们一直在学习的路由方式,在开发中最常使用。
    2. HashRouter:在路径前加入#号成为一个哈希值。Hash模式的好处是,再也不会因为我们刷新而找不到我们的对应路径了。
    3. MemoryRouter:不存储history,所有路由过程保存在内存里,不能进行前进后退,因为地址栏没有发生任何变化。
    4. NativeRouter:经常配合ReactNative使用,多用于移动端,以后ReactNative课程中会详细讲解。
    5. StaticRouter:设置静态路由,需要和后台服务器配合设置,比如设置服务端渲染时使用。

    17、prompt用法讲解

           地址: http://jspang.com/2017/10/22/react-all-01/#10prompt

           动态该改变when的状态那,这里做一个小实例:写一个按钮,然后设置一个power状态,通过点击按钮改变状态,来控制<Prompt>标签的启用和关闭

            

     1 import React from 'react';
     2 import {Prompt} from 'react-router-dom';
     3 export default class jspangb extends React.Component{
     4  
     5  
     6     constructor(props){
     7         super(props);
     8         this.state={
     9             power:false
    10         }
    11         this.changePower=this.changePower.bind(this);  //备注:这个是为了给changePower绑定作用域,如果没有这个的话,方法里的this找不到
    12     }
    13     changePower(){
    14         alert('已经开启');
    15         this.setState({
    16             power:true
    17         })
    18     }
    19  
    20     render(){
    21         return(
    22             <div>
    23                 <p> B页面</p>
    24                 <Prompt message="残忍离开?" when={this.state.power}/>
    25                 <button onClick={this.changePower}>启用</button>
    26             </div>
    27         )
    28     }
    29 }
  • 相关阅读:
    采用闭锁(CountDownLatch)控制线程的先后顺序(一)
    采用java信号量(semaphore)让线程轮流打印
    生产者消费者模式的java实现(实现四)
    生产者消费者模式的java实现(实现三)
    生产者消费者模式的java实现(实现二)
    生产者消费者模式的java实现(实现一)
    求最大子串和 最长子串的java写法
    Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process 异常处理
    定时任务服务器不定时重启原因解析
    centos 6.3 + gerrit-2.8.6 + repo 实践
  • 原文地址:https://www.cnblogs.com/zhaobao1830/p/7998185.html
Copyright © 2020-2023  润新知