1、深入浅出React(一)

2018-05-31  本文已影响65人  怀念不能

深入浅出React(一)

1、create-react-app工具使用

  1. 安装create-react-app
npm install create-react-app -g
  1. 创建项目
creact-react-app demos
cd demos
npm start
  1. 分解应用
    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)

  1. 用户看到的界面(UI),是一个 纯函数(render) 的执行结果,只接受数据(data)作为参数;
  2. 纯函数:没有任何副作用,输出完全依赖于输入的函数;
  3. 对于react开发者,重要的是区分哪些属于data,哪些属于render,要更新界面,要做的就是更新data;
  4. react实践的也是"响应式编程"的思想。
  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树只需要操作有差别的部分。

  1. JSX: 是JavaScript的语法扩展,允许我们在JavaScript中编写HTML一样的代码,最终会编译成普通的JavaScript语句;
  2. 属性使用
  1. JavaScript表达式使用
  1. 样式
  1. 注释
  1. 数组
  1. 事件挂载

3. React数据##

<a id="prop"></a>

  1. prop(property的简写)是从外部传递给组件的数据,一个组件通过定义自己能够接受的prop就定义了自己的对外公共接口;
  2. 每个React组件都是独立存在的模块,组件之外的一切都是外部世界,外部世界就是通过prop来和组件对话的。
class Demo extends Component{
  render(){
    return(
      <div>
        <Child caption = "toProp" initValue = {0}/>//给子组件<Child />传入caption和initValue信息,子组件需定义相关prop接口
      </div>
    )
  }
}
  1. this.prop赋值是React.Component构造函数的工作之一;
  2. 如果一个组件需要定义自己的构造函数,一定要在构造函数的第一行super调用父类也就是React.Component的构造函数;
  3. 如果没有在构造函数中调用super(props),那么组件实例被构造之后,类实例的所有成员就无法通过this.props访问到父组件传递过来的props值。
class Child extends Component{
  constructor(props){
    super(props);
    this.state = {
    //获取外部传入的prop,并用于state初始化
      count: props.initValue || 0,
      caption: props.caption
    }
  }
}

  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验证器

  4. JavaScript基本类型:

    PropTypes.array

    PropTypes.bool

    PropTypes.func

    PropTypes.number

    PropTypes.object

    PropTypes.string

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

  6. ReactElement

    PropTypes.element

  7. 指定类的实例

    PropTypes.instanceOf(Message)

  8. 只接受指定的值:

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

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

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

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

    PropTypes.arrayOf(PropTypes.number)

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

    PropTypes.objectOf(PropTypes.number)

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

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

  13. 在任意类型上加上isRequired使其不为空:

   ` PropTypes.func.isRequired `

eg:

Child.propTypes = {
  initValue: PropTypes.number,
  caption: PropTypes.string
  
}
  1. state代表组件的内部状态,由于React组件不能修改传入的prop,所以需要使用state记录自身数据变化;
constructor(props){
 ...
 this.state = {
   count: props.initValue || 0
 }
}

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

  1. 使用prop给内部子组件传递数据时需要一层一层的传递,即使中间有组件不需要使用,这样比较麻烦;
  2. 使用context可以实现跨级传递。

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
}
```

不积跬步,何以行千里

上一篇下一篇

猜你喜欢

热点阅读