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

React的组件生命周期

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

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

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

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

组件第三阶段:卸载组件

JSX 语法

  1. const names = ['Alice', 'Emily', 'Kate'];
  2.  
  3. ReactDOM.render(
  4. <div>
  5. {
  6. names.map((name) => {
  7. return <div>Hello, {name}!</div>
  8. })
  9. }
  10. </div>,
  11. document.getElementById('example')
  12. );

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

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

  1. {/* 。。。 */}

父组件传向子组件

  1. 子:
    var HelloMessage = React.createClass({
  2. render: function() {
  3. return <h1>Hello {this.props.name}</h1>;
  4. }
  5. });
  6. ---------------------------------------
    父:
  7. ReactDOM.render(
  8. <HelloMessage name="Muyy" />,
  9. document.getElementById('example')
  10. );

变量 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="男">男</option>
  8. <option value="女">女</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和handleSelect
  27. 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 方法可以用来设置组件属性的默认值

  1. var MyTitle = React.createClass({
  2. getDefaultProps : function () {
  3. return {
  4. title : 'Hello World'
  5. };
  6. },
  7.  
  8. render: function() {
  9. return <h1> {this.props.title} </h1>;
  10. }
  11. });
  12.  
  13. ReactDOM.render(
  14. <MyTitle />,
  15. document.body
  16. ); 

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

  1. getInitialState: function() {
  2. return {liked: false};
  3. },

获取真实的DOM节点

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

  1. var MyComponent = React.createClass({
  2. handleClick: function() {
  3. this.refs.myTextInput.focus();
  4. },
  5. render: function() {
  6. return (
  7. <div>
  8. <input type="text" ref="myTextInput" />
  9. <input type="button" value="Focus the text input" onClick={this.handleClick} />
  10. </div>
  11. );
  12. }
  13. });
  14.  
  15. ReactDOM.render(
  16. <MyComponent />,
  17. document.getElementById('example')
  18. );

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

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

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

子组件传向父组件的另一种思路

父组件调用子组件的state、function,除了上面介绍的方法之外,也可以通过ref属性实现。推荐使用这种方式进行子组件向父组件的传递。举个简单的示范:

  1. export default class 父组件a extends React.Component {
  2. constructor(props) {
  3. super(props)
  4. }
  5.  
  6. render() {
  7. return (
  8. <子组件b
  9. ref={r => this.bbbb =r} // bbbb自定义名字
  10. />
  11. )
  12. }
  13. }

经过这样处理后后,现在父组件a中可以通过this.bbbb.state.xxx获取子组件的xxx状态,也可以通过this.bbbb.xxx获取子组件的xxx方法。

React之父子组件传递和其它一些要点的更多相关文章

  1. React中父子组件数据传递

    Vue.js中父子组件数据传递:Props Down ,  Events Up Angular中父子组件数据传递:Props Down,  Events  Up React中父子组件数据传递:Prop ...

  2. 使用react进行父子组件传值

    在单页面里面,父子组件传值是比较常见的,之前一直用vue开发,今天研究了一下react的父子组件传值,和vue差不多的思路,父组件向子组件传值,父通过初始state,子组件通过this.props进行 ...

  3. React中父子组件间的通信问题

    1.https://blog.csdn.net/sinat_17775997/article/details/59103173 (React中父子组件间的通信问题)

  4. vue组件父子组件传递引用类型数据

    今天在写分页功能时,发现父子组件传值时,子组件监听不到父组件中数据的变化,传递的是一个引用类型的数据 其原因是引用类型共用一个内存地址,父子组件用的是同一个对象,故子组件监听不到变化,此时就需要做一个 ...

  5. react.js父子组件通信

    这里通过todolist的功能来说明 父组件: import React,{ Component,Fragment } from 'react'; import TodoItem from './To ...

  6. React中父子组件传值

    一.首先我们先来看父组件向子组件传值 1.1 我们要明白父组件 --> 子组件 是通过props这个属性来传值的 我们来看父组件的代码 import React from 'react'; im ...

  7. React之父子组件之间传值

    1.新增知识点 /** React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. 父子组件:组件的相互调用中,我们把调 ...

  8. vue 父子组件传递数据

    单向数据流: 数据从父级组件传递给子组件,只能单向绑定. 子组件内部不能直接修改从父级传递过来的数据. 解决方法: 可以使用data将父组件传递过来的数据拷贝一份存放起来,再修改拷贝的数据就可以了 / ...

  9. 关于React的父子组件通信等等

    //==================================================此处为父子组件通信 1.子组件调用父组件: 父组件将子组件需要调用方法存入props属性内,子组 ...

随机推荐

  1. Spring Data JPA方法定义规范

    Spring Data Jpa方法定义的规则: (1)简单条件查询 简单条件查询:查询某一个实体类或者集合. 按照Spring Data的规范的规定,查询方法以find | read | get开头, ...

  2. [20180118]tstats的问题.txt

    [20180118]tstats的问题.txt --//关于使用tstats收集处理统计信息,可以看链接http://blog.itpub.net/267265/viewspace-1987839/ ...

  3. java 按字节读写二进制文件(Base64编码解码)

    最近在做项目时遇到这样一个需求:依次读取本地文件夹里所有文件的内容,转为JSON,发送到ActiveMQ的消息队列, 然后从MQ的消息队列上获取文件的信息,依次写到本地.常见的文件类型,比如.txt ...

  4. early_suspend【转】

    android 休眠唤醒机制分析(二) - early_suspend early_suspend是Android休眠流程的第一阶段即浅度休眠,不会受到wake_lock的阻止,一般用于关闭lcd.t ...

  5. 上下文管理器——with语句的实现

    前言 with语句的使用给我们带来了很多的便利,最常用的可能就是关闭一个文件,释放一把锁. 既然with语句这么好用,那我也想让我自己写的代码也能够使用with语句,该怎么实现? 下面具体介绍怎样实现 ...

  6. Django电商项目---完成用户中心(订单中心+收货地址)day7

    完成用户中心(收货地址) df_user/views.py df_user/urls.py templates/df_user/user_center_site.html 界面显示 完成用户中心(全部 ...

  7. 阿里云搭建JAVA WEB环境(SQL Server + TomCat + 配置域名)

    假期刚刚搭完,先写个提纲,今晚写完: 1.申请一个月的免费的云服务器ECS; 2.在云服务器上安装Java开发环境+Sql Server+Tomcat; 3.购买域名并认证,绑定服务器共有IP地址; ...

  8. ELK-logstash-6.3.2部署

    Logstash 是一款强大的数据处理工具,它可以实现数据传输,格式处理,格式化输出,还有强大的插件功能,常用于日志处理. 1. logstash部署 [yun@mini04 software]$ p ...

  9. [Tomcat]The JRE_HOME environment variable is not defined correctly

    在tomcat的bin目录下,双击startup.bat,闪一下,就没了,后来仔细看了一下黑屏闪的内容如下: the JRE_HOME environment variable is not defi ...

  10. 拓普微小尺寸TFT液晶屏-高性价比

    智能模块(Smart LCD)是专为工业显示应用而设计的TFT液晶显示模块. 模块自带主控IC.Flash存储器.实时嵌入式操作系统,客户主机可把要存储的数据(如背景图.图标等)存储到屏的flash中 ...