首页 > 代码库 > 使用React开发的一些注意要点

使用React开发的一些注意要点

react是R系技术栈中最基础同时也是最核心的一环,2年不到获取了62.5k star(截止到目前),足可见其给力程度。下面对一些react日常开发中的注意事项进行罗列。

React的组件生命周期

react主要思想是构建可复用组件来构建用户界面。在react里面一切皆组件。每个组件里面都是有自己的生命周期,这个生命周期规定了组件的状态和方法,分别在哪个阶段执行。下面附上一张RN的生命周期图: 

技术分享

组件第一阶段:初始化、渲染以及装载完成; 

组件第二阶段:组件运行时候的状态 ①:状态变化引发组件的更新和重新渲染到更新完成 

                   ②:父组件属性变化引发组件的更新(是常见的组件之间传递数据和同步状态的手段):比如父组件登录了,子组件也需变成登录状态

组件第三阶段:卸载组件

JSX 语法

const names = [‘Alice‘, ‘Emily‘, ‘Kate‘];ReactDOM.render(  <div>  {    names.map((name) => {      return <div>Hello, {name}!</div>    })  }  </div>,  document.getElementById(‘example‘));

JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。

所以给jsx添加注释只要这样子:

{/* 。。。 */}

父组件传向子组件

子:
var
HelloMessage = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; }});---------------------------------------
父:ReactDOM.render(
<HelloMessage name="Muyy" />, document.getElementById(‘example‘));

变量 HelloMessage 就是相当于一个子组件类。通过this.props.name获取到了Muyy。

另外注意

  1. 所有组件类都必须有自己的 render 方法,用于输出组件。
  2. 组件类的第一个字母必须大写,否则会报错,比如HelloMessage不能写成helloMessage
  3. 组件类只能包含一个顶层标签
  4. class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字

子组件传向父(爷)组件

其实很简单,概括起来就是:react中state改变了,组件才会update。父组件写好state和处理该state的函数,同时将函数名通过props属性值的形式传入子,子调用父的函数,同时引起state变化。

例子1.这里如下图,用户邮箱为父,绿色框为子。 父组件为用户输入的邮箱设好state,即“{email: ‘‘}”,同时写好处理state的函数,即“handleEmail”,这两个名称随意起;再将函数以props的形式传到子组件,子组件只需在事件发生时,调用父组件传过来的函数即可。 

技术分享

技术分享
 1 //子组件 2 var Child = React.createClass({ 3     render: function(){ 4         return ( 5             <div> 6                 请输入邮箱:<input onChange={this.props.handleEmail}/> 7             </div> 8         ) 9     }10 });11 //父组件,此处通过event.target.value获取子组件的值12 var Parent = React.createClass({13     getInitialState: function(){14         return {15             email: ‘‘16         }17     },18     handleEmail: function(event){19         this.setState({email: event.target.value});20     },21     render: function(){22         return (23             <div>24                 <div>用户邮箱:{this.state.email}</div>25                 <Child name="email" handleEmail={this.handleEmail.bind(this)}/>26             </div>27         )28     }29 });30 React.render(31   <Parent />,32   document.getElementById(‘test‘)33 );
demo1 

例子2.有时候往往需要对数据做处理,再传给父组件,比如过滤或者自动补全等等,下面的例子对用户输入的邮箱做简单验证,自动过滤非数字、字母和"@."以外的字符。

技术分享

技术分享
 1 //子组件,handleVal函数处理用户输入的字符,再传给父组件的handelEmail函数 2 var Child = React.createClass({ 3     handleVal: function() { 4         var val = this.refs.emailDom.value; 5         val = val.replace(/[^0-9|a-z|\@|\.]/ig,""); 6         this.props.handleEmail(val); 7     }, 8     render: function(){ 9         return (10             <div>11                 请输入邮箱:<input ref="emailDom" onChange={this.handleVal}/>12             </div>13         )14     }15 });16 //父组件,通过handleEmail接受到的参数,即子组件的值17 var Parent = React.createClass({18     getInitialState: function(){19         return {20             email: ‘‘21         }22     },23     handleEmail: function(val){24         this.setState({email: val});25     },26     render: function(){27         return (28             <div>29                 <div>用户邮箱:{this.state.email}</div>30                 <Child name="email" handleEmail={this.handleEmail.bind(this)}/>31             </div>32         )33     }34 });35 React.render(36   <Parent />,37   document.getElementById(‘test‘)38 );
demo2 

例子3.如果还存在孙子组件的情况呢?如下图,黑框为父,绿框为子,红框为孙,要求子孙的数据都传给爷爷。原理一样的,只是父要将爷爷对孙子的处理函数直接传下去。

技术分享

技术分享
 1 //孙子,将下拉选项的值传给爷爷 2 var Grandson = React.createClass({ 3     render: function(){ 4         return ( 5             <div>性别: 6                 <select onChange={this.props.handleSelect}> 7                     <option value="http://www.mamicode.com/男">男</option> 8                     <option value="http://www.mamicode.com/女">女</option> 9                 </select>10             </div>11         )12     }13 });14 //子,将用户输入的姓名传给爹  15 //对于孙子的处理函数,父只需用props传下去即可16 var Child = React.createClass({17     render: function(){18         return (19             <div>20                 姓名:<input onChange={this.props.handleVal}/>21                 <Grandson handleSelect={this.props.handleSelect}/>22             </div>23         )24     }25 });26 //父组件,准备了两个state,username和sex用来接收子孙传过来的值,对应两个函数handleVal和handleSelect27 var Parent = React.createClass({28     getInitialState: function(){29         return {30             username: ‘‘,31             sex: ‘‘32         }33     },34     handleVal: function(event){35         this.setState({username: event.target.value});36     },37     handleSelect: function(event) {38         this.setState({sex: event.target.value});39     },40     render: function(){41         return (42             <div>43                 <div>用户姓名:{this.state.username}</div>44                 <div>用户性别:{this.state.sex}</div>45                 <Child handleVal={this.handleVal.bind(this)} handleSelect={this.handleSelect.bind(this)}/>46             </div>47         )48     }49 });50 React.render(51   <Parent />,52   document.getElementById(‘test‘)53 );
demo3

getDefaultProps && getInitialState

getDefaultProps 方法可以用来设置组件属性的默认值

var MyTitle = React.createClass({  getDefaultProps : function () {    return {      title : ‘Hello World‘    };  },  render: function() {     return <h1> {this.props.title} </h1>;   }});ReactDOM.render(  <MyTitle />,  document.body); 

getInitialState 方法可以用来设置初始状态

  getInitialState: function() {    return {liked: false};  },

获取真实的DOM节点

从组件获取真实 DOM 的节点,这时就要用到 ref 属性

var MyComponent = React.createClass({  handleClick: function() {    this.refs.myTextInput.focus();  },  render: function() {    return (      <div>        <input type="text" ref="myTextInput" />        <input type="button" value="http://www.mamicode.com/Focus the text input" onClick={this.handleClick} />      </div>    );  }});ReactDOM.render(  <MyComponent />,  document.getElementById(‘example‘));

上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。

需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。

React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown 、CopyScroll 等,完整的事件清单请查看官方文档。

使用React开发的一些注意要点