4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
了解一个React组件_明天回火星-CSDN博客
来自 : CSDN技术社区 发布时间:2021-03-24


从一个简单的组件开始

标题叫“一个简单的组件” 于是先来看下官方网站上一个叫做“A Simple Component”的例子来感受下

var HelloMessage React.createClass({ render: function() { return div Hello {this.props.name} /div }})React.render( HelloMessage name John / , mountNode)

好的 通过React提供的工厂方法 我们创建了一个组件 在这里 我们认为createClass创建了一张blueprint 而通过jsx语法创建的 HelloMessage name John / 则返回一个ReactElement对象来具体地告诉React要如何渲染组件 因为除了blueprint以外还需要一些外部状态的传入 这等同于调用React.createElement(HelloMessage, { name: John }, Hello , this.props.name)。

之后 React就可以根据ReactElement对象 把组件挂载到页面的某个节点上去 也就是React.render方法在做的事情 这个方法返回一个组件的实例 同时也意味着你可以在已有项目中的一小部分尝试React。

下面来具体介绍下。

JSX

上面的例子里看着像是把HTML写在了Js里 实际上是通过一种更加清晰易读且易维护的语法JSX来创建ReactElement对象。对React来说JSX是可选的 如果真的不喜欢也可以用React.createElement这个api。

当然有JSX语法的js文件是不能直接在浏览器中运行的 我们可以用官方的JSXTransformer或者是babel来转换。

需要注意的是class和for这两个HTML属性 由于组件的属性实际是以对象形式传递的 比如上面的{ name: John } 另外js不允许关键字作为属性名 所以需要分别用className和htmlFor代替。

创建一个组件

创建组件的时候需要给React.createClass提供一个对象 这个对象必须包含一个render方法和若干可选的生命周期方法。

要注意的是我们需要保证render函数是纯函数 即同样的输入始终返回相同的输出 并且执行过程中没有副作用 和DOM交互或者发Ajax请求 。但一个组件要和DOM交互或者发Ajax请求需求是很正常的 那么就要用到其他生命周期方法了。

除此之外 更重要的部分是 让一个组件可以工作除了有blueprint外 还需要组件状态。对于一个React组件来说 分为不可变状态this.props和可变状态this.states。

我们可以通过this.props决定一个组件内的部分呈现内容 比如上例中我们希望呈现的名字是John 且不会改变。然而对于一个DropDownList而言 仅在点击它时 一个下拉列表才会显示出来 那么我们认为这个下拉列表是否显示就是一个可变状态。

说到可变状态 那么要这么变 React并不希望我们直接修改this.states 我们需要使用this.setState的方式修改状态 因为每次调用this.setState render方法都会被再次调用 同时也会调用一些相关的生命周期函数。this.setState接受一个对象作为新状态的patch 也就是说这个对象不会覆盖现有的this.states 而是一个类似extend的行为。

我们也可以提供一些默认状态

getDefaultProps () { return { name: defaultName };},getInitialState: function() { return { listShowed: false };},

其中getDefaultProps仅会被调用一次 这里的意思是无论你会创建多少个ReactElement 这个函数都只执行一次 之后的默认props都会直接使用改函数的返回值。

这里需要提一下React提供以ES6的方式创建组件 有意思的是ES6的版本用的是React.Component 在语意上比createClass更加明确。getDefaultProps和getInitialState在ES6的版本中有些不太一样 相对与getDefaultProps ES6将默认属性对象作为了构造函数的一个属性 而getInitialState则变成了在其构造器函数中给this.state赋值 来看一个栗子

class HelloMessage extends React.Component { constructor (props, context) { super(props, context) this.state { } // 初始化状态 } render () { return div Hello {this.props.name} /div }}HelloMessage.defaultProps { name: defaultName }
组件的生命周期

之前的部分一直有提到生命周期函数 下面就来介绍下

componentWillMount会在组件即将被挂载时调用 此时this.refs对象为空对象。如果在该函数中使用this.setState 那么会更新this.states对象 而render依然只会调用一次 相当于是可以覆盖getInitialState返回的对象 虽然我觉得这没什么意义。

componentDidMount是非常常用的生命周期方法 仅当组件被挂载后调用一次 这意味着可以在这个函数中进行一些DOM操作等 比如希望组件中的一个textbox可以再挂载后自动获取焦点

componentDidMount () { const textbox React.findDOMNode(this.refs.text) if (this.props.autoFocus) textbox.focus()}

componentWillReceiveProps在将要接受新的props时被调用 不是说props是不可变状态吗 情况通常是这样的 当一个父组件包含了一个子组件 子组件的一个props的值是父组件的states的值 那么当父组件可变状态改变时 子组件的props也更新了 于是调用了这个函数。

componentWillReceiveProps (nextProps) { if (this.props.disabled ! nextProps.disabled) { // disabled这个属性改变了 }}

这个生命周期函数componentWillReceiveProps提供了更新states的机会 可以调用this.setState 也是唯一可以在组件更新周期中调用this.setState的函数。

shouldComponentUpdate是在更新前根据该函数的返回值决定是否进行这次更新。

shouldComponentUpdate (nextProps, nextState) { // 比较props或者states 返回true则更新照常 返回false则取消更新 且不会调用下面的两个生命周期函数}

考虑这种情况 父组件有子组件A和子组件B 当父组件调用this.setState更新一个作为子组件A属性的state时 render方法被再次调用 此时组件A和组件B同时被更新 其实真正改变的只有组件A 但组件B也同时被要求更新了 这是没有必要的 于是shouldComponentUpdate就显的有用了 在该函数体内比较props或是states 如果没有改变就取消这个更新 这对性能上算是一个提升。

但如果是复杂对象的比较就比较麻烦了 因为我们无法通过 来判断两个对象的键值是否都相等 于是我们就希望我们的对象是不可变的 immutable 。这里不再展开了 大家可以先自行探索 之后再写这个部分的文字 并介绍immutable.js

componentWillUpdate在组件被更新前调用一次 可以用来做一些更新前的准备工作 举个栗子

componentWillUpdate (nextProps, nextState) { if (!this.props.isShowed nextProps.isShowed) { // 比如下拉菜单此时变的显示了 可以对此监听一些事件什么的 } if (this.props.isShowed !nextProps.isShowed) { // 比如下拉菜单隐藏了 可以在这里取消事件监听 }}

组件更新前事情还蛮多的...

componentDidUpdate在组件更新完成后调用 可以考虑在这个函数中执行一些DOM操作什么的。

注意 绝对不要在componentWillUpdate和componentDidUpdate中调用this.setState方法 否则将导致无限循环调用。

componentWillUnmount会在组件即将从挂载点移去时调用 此方法专门用来『擦屁股』 比如去除即将被销毁的DOM节点的引用 或者是清除计时器 取消监听的时间等等。



文 leozdgao 简书作者

\"\" \"\" \"\" 点赞 \"\" \"\" 评论

本文链接: http://reactana.immuno-online.com/view-692246.html

发布于 : 2021-03-24 阅读(0)
公司介绍
品牌分类
其他
联络我们
服务热线:4000-520-616
(限工作日9:00-18:00)
QQ :1570468124
手机:18915418616