资讯专栏INFORMATION COLUMN

1、深入浅出React(一)

davidac / 899人阅读

摘要:中的事件不存在以上问题挂载的每个函数都可以控制在组件中,不会污染全局空间中没有产生直接使用的,而是使用了事件委托方式处理,无论有多少个出现,其实最后都只在树上添加了一个事件处理函数,挂在最顶层的节点上。

深入浅出React(一) 1、create-react-app工具使用

安装create-react-app

npm install create-react-app -g

创建项目

creact-react-app demos
cd demos
npm start

分解应用

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新的前端思维模式

数据驱动渲染

开发者不需要像jQuery一样详细的操作DOM着重于‘如何去做’,只需要着重于“我要显示什么”,而不用操心“怎样去做”;

react理念UI = reader(data)

用户看到的界面(UI),是一个 纯函数(render) 的执行结果,只接受数据(data)作为参数;

纯函数:没有任何副作用,输出完全依赖于输入的函数;

对于react开发者,重要的是区分哪些属于data,哪些属于render,要更新界面,要做的就是更新data;

react实践的也是"响应式编程"的思想。

3、Virtual DOM

每次render函数被调用,都要把整个组件重新渲染一遍会浪费,而react对此利用Virtual DOM,让每次渲染都只从新渲染最少的DOM;

DOM树:HTML是结构化文本,而DOM是结构化文本的抽象表达形式,浏览器在渲染HTML格式网页时,会先将HTML文本解析以构建DOM树,然后根据DOM树渲渲染出用户看到界面,当改变内容时,就去改变DOM树上的节点;

虽然DOM树只是一些简单的JavaScript语句,但DOM操作会引起浏览器对网页的从新布局和绘制,所以Web前端开发优化原则之一: 尽量较少DOM操作

react开发会中jsx语句,将被Babel解析为创建React组件或HTML元素的语句,但React并不会通过其直接构建或操作DOM树,而是先构建Virtual DOM;

DOM树是对HTML的抽象,而Virtual DOM是对DOM树的抽象;

Vritual DOM不触及浏览器,只存在于JavaScript空间的树形结构,每次自上而下的渲染React组件时,都会对比此次产生的Vritual DOM和上一次产生的,然后真正的DOM树只需要操作有差别的部分。

4、JSX

JSX: 是JavaScript的语法扩展,允许我们在JavaScript中编写HTML一样的代码,最终会编译成普通的JavaScript语句;

属性使用

自定义属性data-*;

class和for为JavaScript保留关键字,所以class和for属性使用className和htmlFor;

JavaScript表达式使用

JSX允许在闭合标签中使用JavaScript表达式,但必须用{}包裹;

JavaScript表达式要求必须有 返回值 ,所以不能直接使用 if else 语句,但可以使用三元操作表达式和&&,||这样的比较运算符来书写;

如果确实需要使用 if else语句,可以写在函数中,然后在{}中调用。

样式

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

注释

标签内注意需要写在{}中。

数组

JSX中的数组会自动展开;

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

事件挂载

JSX中可以通过onClick(HTML原生为onclick)

HTML直接使用onclick缺点:

onclick添加的事件处理函数是在全局环境下执行,污染全局环境,容易产生意想不到的后果;

给很多DOM元素添加onclick事件,可能会影响网页的性能;

对于使用onclick的DOM元素,如果要动态的从DOM树种删除,需要把对应的事件处理器注销,否则可能造成内存泄漏。

JSX中的onClick事件(不存在以上问题)

onClick挂载的每个函数都可以控制在组件中,不会污染全局空间;

JSX中onClick没有产生直接使用onclick的HTML,而是使用了 事件委托 方式处理,无论有多少个onClick出现,其实最后都只在DOM树上添加了一个事件处理函数,挂在最顶层的DOM节点上。

所有的点击事件都被这个事件处理函数捕获,然后根据具体组件分配给特定函数,所以性能较高;

因为React控制了组件的生命周期,在unmount的时候能够清除相关的所有事件处理函数,内存泄漏问题解决。

function Demo(){
  const name = "jsx";
  const arr = [
    

数组

数组会自动展开,注意添加key属性

]; const func = () => { let result = "hello"; if (name){ result += name; } else { result += "world"; } return result; }; return (

{/*注释*/}

hello {name || "world"}

hello {name && "world"}

{func()}

{arr}
) }

3. React数据

React的prop

prop(property的简写)是从外部传递给组件的数据,一个组件通过定义自己能够接受的prop就定义了自己的对外公共接口;

每个React组件都是独立存在的模块,组件之外的一切都是外部世界,外部世界就是通过prop来和组件对话的。

给prop赋值

class Demo extends Component{
  render(){
    return(
      
//给子组件传入caption和initValue信息,子组件需定义相关prop接口
) } }

读取prop值

this.prop赋值是React.Component构造函数的工作之一;

如果一个组件需要定义自己的构造函数,一定要在构造函数的第一行super调用父类也就是React.Component的构造函数;

如果没有在构造函数中调用super(props),那么组件实例被构造之后,类实例的所有成员就无法通过this.props访问到父组件传递过来的props值。

class Child extends Component{
  constructor(props){
    super(props);
    this.state = {
    //获取外部传入的prop,并用于state初始化
      count: props.initValue || 0,
      caption: props.caption
    }
  }
}

propTypes检查

prop是组件的对外接口,所以一个组件该声明自己的接口规范,规范组件支持哪些prop,每个prop该是什么样的格式;

React通过propTypes来规范,因为propTypes已经从React包中分离出来,所以新版React中无法使用React.PropTypes.*,需导入prop-types
即安装:npm install prop-type --save导入import PropTypes from ("prop-types")

propTypes验证器

JavaScript基本类型:

PropTypes.array

PropTypes.bool

PropTypes.func

PropTypes.number

PropTypes.object

PropTypes.string

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

ReactElement

PropTypes.element

指定类的实例

PropTypes.instanceOf(Message)

只接受指定的值:

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

多个对象类型中的一个:

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

指定类型组成的数组:

PropTypes.arrayOf(PropTypes.number)

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

PropTypes.objectOf(PropTypes.number)

符合指定格式的对象:

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

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

PropTypes.func.isRequired

eg:

Child.propTypes = {
  initValue: PropTypes.number,
  caption: PropTypes.string
  
}

React的state

state代表组件的内部状态,由于React组件不能修改传入的prop,所以需要使用state记录自身数据变化;

state初始化

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

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

读取和更新state

读取this.state

更新this.setState({})

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

prop和state对比

prop用于定义外部接口,state用于记录内部状态;

prop的赋值在外部世界使用组件时,state的赋值在组件内部;

组件不应该改变prop的值,而state的存在就是为了让组件来改变。

React的context

使用prop给内部子组件传递数据时需要一层一层的传递,即使中间有组件不需要使用,这样比较麻烦;

使用context可以实现跨级传递。

context使用步骤

父组件通过getChildContext()方法将需要传入的信息放进context,并声明childContextTypes(如果不声明无法再组件中使用getChildContext());

要使用的子组件中通过声明contextTypes(需要和父组件一致)就可以通过组件实例的context属性访问接收到的数据;

无状态的组件可以在函数参数中获取context;而又状态的组件可以通过this.context和生命周期函数获取context。

eg:
父组件

class Parent extends React.Component{
  getChildContext(){
    return {color: "red"}      
  }
  
  render(){
    return(
      
) } } Parents.childContextTypes = { color: PropTypes.string.isRequired }
(有状态)子组件:
 class Child extends React.Component{
   render(){
     return(
       

有状态的组件可以通过this.context获取

) } } Child.contextTypes = { color: PropTypes.string.isRequired }
(无状态)孙子组件:
 function Grandchild(context){
   return(
     

无状态组件可以直接在函数的参数中获取

) } Grandchild.contextTypes = { color:PropTypes.string.isRequired }
不积跬步,何以行千里

持续加载中.....

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92989.html

相关文章

  • React 深入系列1React 中的元素、组件、实例和节点

    摘要:中的元素组件实例和节点,是中关系密切的个概念,也是很容易让初学者迷惑的个概念。组件和元素关系密切,组件最核心的作用是返回元素。只有组件实例化后,每一个组件实例才有了自己的和,才持有对它的节点和子组件实例的引用。 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解,以及在项目中更加灵活地使用React。 React 中的元素、组件、实...

    LeviDing 评论0 收藏0
  • React 深入系列1:React 中的元素、组件、实例和节点

    摘要:中的元素组件实例和节点,是中关系密切的个概念,也是很容易让初学者迷惑的个概念。组件和元素关系密切,组件最核心的作用是返回元素。只有组件实例化后,每一个组件实例才有了自己的和,才持有对它的节点和子组件实例的引用。 文:徐超,《React进阶之路》作者授权发布,转载请注明作者及出处 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解...

    techstay 评论0 收藏0
  • 深入react技术栈》学习笔记()初入React世界

    摘要:前言以深入学习技术栈为线索,记录下学习的重要知识内容。要传入时,必须使用属性表达式。如果要使用自定义属性,要使用前缀这与标准是一致的。 前言 以《深入学习react技术栈》为线索,记录下学习React的重要知识内容。本系列文章没有涵盖全部的react知识内容,只是记录下了学习之路上的重要知识点,一方面是自己的总结,同时拿出来和在学习react的人们一块分享,共同进步。 正文 一:rea...

    verano 评论0 收藏0
  • React 深入系列7:React 常用模式

    摘要:本篇是深入系列的最后一篇,将介绍开发应用时,经常用到的模式,这些模式并非都有官方名称,所以有些模式的命名并不一定准确,请读者主要关注模式的内容。 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解,以及在项目中更加灵活地使用React。 本篇是React深入系列的最后一篇,将介绍开发React应用时,经常用到的模式,这些模式并非都有...

    Chao 评论0 收藏0
  • React 深入系列3:Props 和 State

    摘要:当真正执行状态修改时,依赖的并不能保证是最新的,因为会把多次的修改合并成一次,这时,还是等于这几次修改发生前的。下篇预告深入系列组件的生命周期新书推荐进阶之路作者徐超毕业于浙江大学,硕士,资深前端工程师,长期就职于能源物联网公司远景智能。 文:徐超,《React进阶之路》作者授权发布,转载请注明作者及出处 React 深入系列3:Props 和 State React 深入系列,深...

    endiat 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<