1、深入浅出React(一)

前端之家收集整理的这篇文章主要介绍了1、深入浅出React(一)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

深入浅出React(一)

1、create-react-app工具使用

  1. 安装create-react-app

    npm install create-react-app -g
  2. 创建项目

    creact-react-app demos
    cd demos
    npm start
  3. 分解应用
  4. @H_404_19@

    package.json

    "scripts": {
      "start": "react-scripts start","build": "react-scripts build","test": "react-scripts test --env=jsdom","eject": "react-scripts eject"
    }

    npm start启动开发环境,npm run build创建生产环境优化代码npm test用于测试单元,npm run eject把潜藏在react-scripts中的一序列技术栈“弹射”到
    应用的顶端,此命令不可逆且会改变和增加一些文件

    2、react新的前端思维模式

    • 数据驱动渲染
    1. 开发者不需要像jQuery一样详细的操作DOM着重于‘如何去做’,只需要着重于“我要显示什么”,而不用操心“怎样去做”;
    2. react理念UI = reader(data)
    3. @H_404_19@
      1. 用户看到的界面(UI),是一个 函数(render) 的执行结果,只接受数据(data)作为参数;
      2. 函数:没有任何副作用,输出完全依赖于输入的函数
      3. 对于react开发者,重要的是区分哪些属于data,哪些属于render,要更新界面,要做的就是更新data;
      4. react实践的也是"响应式编程"的思想。
      5. @H_404_19@
      • 3、Virtual DOM
      1. 每次render函数调用,都要把整个组件重新渲染一遍会浪费,而react对此利用Virtual DOM,让每次渲染都只从新渲染最少的DOM;
      2. DOM树:HTML是结构化文本,而DOM是结构化文本的抽象表达形式,浏览器在渲染HTML格式网页时,会先将HTML文本解析以构建DOM树,然后根据DOM树渲渲染出用户看到界面,当改变内容时,就去改变DOM树上的节点;
      3. 虽然DOM树只是一些简单的JavaScript语句,但DOM操作会引起浏览器对网页的从新布局和绘制,所以Web前端开发优化原则之一: 尽量较少DOM操作
      4. react开发会中jsx语句,将被Babel解析为创建React组件或HTML元素的语句,但React并不会通过其直接构建或操作DOM树,而是先构建Virtual DOM;
      5. DOM树是对HTML的抽象,而Virtual DOM是对DOM树的抽象;
      6. Vritual DOM不触及浏览器,只存在于JavaScript空间的树形结构,每次自上而下的渲染React组件时,都会对比此次产生的Vritual DOM和上一次产生的,然后真正的DOM树只需要操作有差别的部分。
      7. @H_404_19@
        • 4、JSX
        1. JSX: 是JavaScript的语法扩展,允许我们在JavaScript中编写HTML一样的代码,最终会编译成普通的JavaScript语句;
        2. 属性使用

          • 自定义属性data-*;
          • class和for为JavaScript保留关键字,所以class和for属性使用className和htmlFor;
        3. JavaScript表达式使用

          • JSX允许在闭合标签中使用JavaScript表达式,但必须用{}包裹;
          • JavaScript表达式要求必须有 返回值 ,所以不能直接使用 if else 语句,但可以使用三元操作表达式和&&,||这样的比较运算符来书写;
          • 如果确实需要使用 if else语句,可以写在函数中,然后在{}中调用
        4. 样式

          • 通过style属性定义,单属性值不能是字符串只能是对象,且属性名需要使用驼峰命名法(font-size变为fontSize)。
        5. 注释

          • 标签内注意需要写在{}中。
        6. 数组

          • JSX中的数组会自动展开;
          • 注意如果数组或迭代器中的每一项都是HTML标签或组件,那么它们必须要拥有唯一的key属性,这样有助于React的DIFF算法,实现最高效的DOM更新。
        7. 事件挂载

          • JSX中可以通过onClick(HTML原生为onclick)
          • HTML直接使用onclick缺点:

            1. onclick添加的事件处理函数是在全局环境下执行,污染全局环境,容易产生意想不到的后果;
            2. 给很多DOM元素添加onclick事件,可能会影响网页的性能
            3. 对于使用onclick的DOM元素,如果要动态的从DOM树种删除,需要把对应的事件处理器注销,否则可能造成内存泄漏。
            4. @H_404_19@
            5. JSX中的onClick事件(不存在以上问题)

              1. onClick挂载的每个函数都可以控制在组件中,不会污染全局空间;
              2. JSX中onClick没有产生直接使用onclick的HTML,而是使用了 事件委托 方式处理,无论有多少个onClick出现,其实最后都只在DOM树上添加了一个事件处理函数,挂在最顶层的DOM节点上。
              3. 所有的点击事件都被这个事件处理函数捕获,然后根据具体组件分配给特定函数,所以性能较高;
              4. 因为React控制了组件的生命周期,在unmount的时候能够清除相关的所有事件处理函数,内存泄漏问题解决
              5. @H_404_19@
                function Demo(){
                  const name = 'jsx';
                  const arr = [
                    <h3 key = {0}>数组</h3>
                    <p key = {1}>数组会自动展开,注意添加key属性</p>
                  ];
                  const func = () => {
                    let result = 'hello';
                    if (name){
                      result += name;
                    } else {
                      result += 'world';
                    }
                    return result;
                  };
                  return (
                    <div>
                      <h2></h2>
                      {/*注释*/}
                      <p style = {{color: 'red',fontSize: '14px'}}>hello {name || 'world'}</p>
                      <p className = {name ? 'classA' : 'classB'}>
                        hello {name && 'world'}
                      </p>
                      <p>
                        {func()}
                      </p>
                      {arr}
                    </div>
                  )
                }
        8. @H_404_19@

          3. React数据

          • React的prop

            1. prop(property的简写)是从外部传递给组件的数据,一个组件通过定义自己能够接受的prop就定义了自己的对外公共接口;
            2. 每个React组件都是独立存在的模块,组件之外的一切都是外部世界,外部世界就是通过prop来和组件对话的。
            3. @H_404_19@
              • 给prop赋值

                class Demo extends Component{
                  render(){
                    return(
                      <div>
                        <Child caption = "toProp" initValue = {0}/>//给子组件<Child />传入caption和initValue信息,子组件需定义相关prop接口
                      </div>
                    )
                  }
                }
              • 读取prop值

                1. this.prop赋值是React.Component构造函数的工作之一;
                2. 如果一个组件需要定义自己的构造函数,一定要在构造函数的第一行super调用父类也就是React.Component的构造函数
                3. 如果没有在构造函数调用super(props),那么组件实例被构造之后,类实例的所有成员就无法通过this.props访问到父组件传递过来的props值。
                4. @H_404_19@
                class Child extends Component{
                  constructor(props){
                    super(props);
                    this.state = {
                    //获取外部传入的prop,并用于state初始化
                      count: props.initValue || 0,caption: props.caption
                    }
                  }
                }
              • propTypes检查

                1. prop是组件的对外接口,所以一个组件该声明自己的接口规范,规范组件支持哪些prop,每个prop该是什么样的格式;
                2. React通过propTypes来规范,因为propTypes已经从React包中分离出来,所以新版React中无法使用React.PropTypes.*,需导入prop-types
                  即安装:npm install prop-type --save导入import PropTypes from ('prop-types')
                3. propTypes验证器

                  1. JavaScript基本类型:

                    PropTypes.array

                    PropTypes.bool

                    PropTypes.func

                    PropTypes.number

                    PropTypes.object

                    PropTypes.string

                  2. 可以被渲染为子节点的对象,包括数值、字符串ReactElement(指的是JSX中的闭合标签)或数组:
                    PropTypes.node
                  3. ReactElement

                    PropTypes.element

                  4. 指定类的实例

                    PropTypes.instanceOf(Message)

                  5. 只接受指定的值:

                    PropTypes.oneOf(['News','Photos'])

                  6. 多个对象类型中的一个:

                    PropTypes.oneOfType([
                    PropTypes.string,
                    PropTypes.number,
                    PropTypes.instanceOf(Message)
                    ])

                  7. 指定类型组成的数组:

                    PropTypes.arrayOf(PropTypes.number)

                  8. 指定类型的属性构成的对象:

                    PropTypes.objectOf(PropTypes.number)

                  9. 符合指定格式的对象:

                    PropTypes.shape({
                    color: PropTypes.string,
                    fontSize: PropTypes.number
                    })

                  10. 在任意类型上加上isrequired使其不为空:

                    PropTypes.func.isrequired

                  11. @H_404_19@ @H_404_19@
          eg:
          
          Child.propTypes = {
            initValue: PropTypes.number,caption: PropTypes.string
            
          }
          • React的state
          1. state代表组件的内部状态,由于React组件不能修改传入的prop,所以需要使用state记录自身数据变化;

            • state初始化

              constructor(props){
               ...
               this.state = {
                 count: props.initValue || 0
               }
              }

              注意:使用React.createClass方法创建出来的组件类,通过getInitialState方法获取初始值,但这种方法已被废弃。

            • 读取和更新state

              1. 读取this.state
              2. 更新this.setState({})
              3. @H_404_19@
          2. @H_404_19@

            注意:不要直接修改this.state的值,虽然能够改变组件的内部状态,但只是野蛮的修改了state,却不会驱动组件从新渲染,所以变化不会反应到界面
            而,this.setState()所做的事是先改变this.state的值,然后驱动组件更新

            • prop和state对比

              1. prop用于定义外部接口,state用于记录内部状态;
              2. prop的赋值在外部世界使用组件时,state的赋值在组件内部;
              3. 组件不应该改变prop的值,而state的存在就是为了让组件来改变。
              4. @H_404_19@
            • React的context
            1. 使用prop给内部子组件传递数据时需要一层一层的传递,即使中间有组件不需要使用,这样比较麻烦;
            2. 使用context可以实现跨级传递。

              • context使用步骤

                1. 父组件通过getChildContext()方法将需要传入的信息放进context,并声明childContextTypes(如果不声明无法再组件中使用getChildContext());
                2. 要使用的子组件中通过声明contextTypes(需要和父组件一致)就可以通过组件实例的context属性访问接收到的数据;
                3. 无状态的组件可以在函数参数中获取context;而又状态的组件可以通过this.context和生命周期函数获取context。
                4. @H_404_19@
            3. @H_404_19@

              eg:
              父组件

              class Parent extends React.Component{
                getChildContext(){
                  return {color: "red"}      
                }
                
                render(){
                  return(
                    <div>
                      <Child />
                    </div>
                  )
                }
              }
              
              Parents.childContextTypes = {
                color: PropTypes.string.isrequired
              }
              (有状态)子组件:
              class Child extends React.Component{
                 render(){
                   return(
                     <div>
                       <p style = {{color:{this.context.color}}}>有状态的组件可以通过this.context获取</p>
                       <Grandchild />
                     </div>
                   )
                 }
               }
               
               Child.contextTypes = {
                 color: PropTypes.string.isrequired
               }
              (无状态)孙子组件:
              function Grandchild(context){
                 return(
                   <p style = {{color: {context.color}}}>无状态组件可以直接在函数的参数中获取</p>
                 )
               }
               
               Grandchild.contextTypes = {
                 color:PropTypes.string.isrequired
               }

              不积跬步,何以行千里
              • 持续加载中.....

猜你在找的React相关文章