React之父子组件传递和其它一些要点
react是R系技术栈中最基础同时也是最核心的一环,2年不到获取了62.5k star(截止到目前),足可见其给力程度。下面对一些react日常开发中的注意事项进行罗列。
React的组件生命周期
react主要思想是构建可复用组件来构建用户界面。在react里面一切皆组件。每个组件里面都是有自己的生命周期,这个生命周期规定了组件的状态和方法,分别在哪个阶段执行。下面附上一张React的生命周期图:
组件第一阶段:初始化、渲染以及装载完成;
组件第二阶段:组件运行时候的状态 ①:状态变化引发组件的更新和重新渲染到更新完成
②:父组件属性变化引发组件的更新(是常见的组件之间传递数据和同步状态的手段):比如父组件登录了,子组件也需变成登录状态
组件第三阶段:卸载组件
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。
另外注意
- 所有组件类都必须有自己的
render
方法,用于输出组件。 - 组件类的第一个字母必须大写,否则会报错,比如
HelloMessage
不能写成helloMessage
- 组件类只能包含一个顶层标签
class
属性需要写成className
,for
属性需要写成htmlFor
,这是因为class
和for
是 JavaScript 的保留字
子组件传向父(爷)组件
其实很简单,概括起来就是:react中state改变了,组件才会update。父组件写好state和处理该state的函数,同时将函数名通过props属性值的形式传入子,子调用父的函数,同时引起state变化。
例子1.这里如下图,用户邮箱为父,绿色框为子。 父组件为用户输入的邮箱设好state,即“{email: ''}”,同时写好处理state的函数,即“handleEmail”,这两个名称随意起;再将函数以props的形式传到子组件,子组件只需在事件发生时,调用父组件传过来的函数即可。
//子组件
var Child = React.createClass({
render: function(){
return (
<div>
请输入邮箱:<input onChange={this.props.handleEmail}/>
</div>
)
}
});
//父组件,此处通过event.target.value获取子组件的值
var Parent = React.createClass({
getInitialState: function(){
return {
email: ''
}
},
handleEmail: function(event){
this.setState({email: event.target.value});
},
render: function(){
return (
<div>
<div>用户邮箱:{this.state.email}</div>
<Child name="email" handleEmail={this.handleEmail.bind(this)}/>
</div>
)
}
});
React.render(
<Parent />,
document.getElementById('test')
);
demo1
例子2.有时候往往需要对数据做处理,再传给父组件,比如过滤或者自动补全等等,下面的例子对用户输入的邮箱做简单验证,自动过滤非数字、字母和"@."以外的字符。
//子组件,handleVal函数处理用户输入的字符,再传给父组件的handelEmail函数
var Child = React.createClass({
handleVal: function() {
var val = this.refs.emailDom.value;
val = val.replace(/[^0-9|a-z|\@|\.]/ig,"");
this.props.handleEmail(val);
},
render: function(){
return (
<div>
请输入邮箱:<input ref="emailDom" onChange={this.handleVal}/>
</div>
)
}
});
//父组件,通过handleEmail接受到的参数,即子组件的值
var Parent = React.createClass({
getInitialState: function(){
return {
email: ''
}
},
handleEmail: function(val){
this.setState({email: val});
},
render: function(){
return (
<div>
<div>用户邮箱:{this.state.email}</div>
<Child name="email" handleEmail={this.handleEmail.bind(this)}/>
</div>
)
}
});
React.render(
<Parent />,
document.getElementById('test')
);
demo2
例子3.如果还存在孙子组件的情况呢?如下图,黑框为父,绿框为子,红框为孙,要求子孙的数据都传给爷爷。原理一样的,只是父要将爷爷对孙子的处理函数直接传下去。
//孙子,将下拉选项的值传给爷爷
var Grandson = React.createClass({
render: function(){
return (
<div>性别:
<select onChange={this.props.handleSelect}>
<option value="男">男</option>
<option value="女">女</option>
</select>
</div>
)
}
});
//子,将用户输入的姓名传给爹
//对于孙子的处理函数,父只需用props传下去即可
var Child = React.createClass({
render: function(){
return (
<div>
姓名:<input onChange={this.props.handleVal}/>
<Grandson handleSelect={this.props.handleSelect}/>
</div>
)
}
});
//父组件,准备了两个state,username和sex用来接收子孙传过来的值,对应两个函数handleVal和handleSelect
var Parent = React.createClass({
getInitialState: function(){
return {
username: '',
sex: ''
}
},
handleVal: function(event){
this.setState({username: event.target.value});
},
handleSelect: function(event) {
this.setState({sex: event.target.value});
},
render: function(){
return (
<div>
<div>用户姓名:{this.state.username}</div>
<div>用户性别:{this.state.sex}</div>
<Child handleVal={this.handleVal.bind(this)} handleSelect={this.handleSelect.bind(this)}/>
</div>
)
}
});
React.render(
<Parent />,
document.getElementById('test')
);
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="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
、Copy
、Scroll
等,完整的事件清单请查看官方文档。
子组件传向父组件的另一种思路
父组件调用子组件的state、function,除了上面介绍的方法之外,也可以通过ref属性实现。推荐使用这种方式进行子组件向父组件的传递。举个简单的示范:
export default class 父组件a extends React.Component {
constructor(props) {
super(props)
} render() {
return (
<子组件b
ref={r => this.bbbb =r} // bbbb自定义名字
/>
)
}
}
经过这样处理后后,现在父组件a中可以通过this.bbbb.state.xxx获取子组件的xxx状态,也可以通过this.bbbb.xxx获取子组件的xxx方法。
React之父子组件传递和其它一些要点的更多相关文章
- React中父子组件数据传递
Vue.js中父子组件数据传递:Props Down , Events Up Angular中父子组件数据传递:Props Down, Events Up React中父子组件数据传递:Prop ...
- 使用react进行父子组件传值
在单页面里面,父子组件传值是比较常见的,之前一直用vue开发,今天研究了一下react的父子组件传值,和vue差不多的思路,父组件向子组件传值,父通过初始state,子组件通过this.props进行 ...
- React中父子组件间的通信问题
1.https://blog.csdn.net/sinat_17775997/article/details/59103173 (React中父子组件间的通信问题)
- vue组件父子组件传递引用类型数据
今天在写分页功能时,发现父子组件传值时,子组件监听不到父组件中数据的变化,传递的是一个引用类型的数据 其原因是引用类型共用一个内存地址,父子组件用的是同一个对象,故子组件监听不到变化,此时就需要做一个 ...
- react.js父子组件通信
这里通过todolist的功能来说明 父组件: import React,{ Component,Fragment } from 'react'; import TodoItem from './To ...
- React中父子组件传值
一.首先我们先来看父组件向子组件传值 1.1 我们要明白父组件 --> 子组件 是通过props这个属性来传值的 我们来看父组件的代码 import React from 'react'; im ...
- React之父子组件之间传值
1.新增知识点 /** React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. 父子组件:组件的相互调用中,我们把调 ...
- vue 父子组件传递数据
单向数据流: 数据从父级组件传递给子组件,只能单向绑定. 子组件内部不能直接修改从父级传递过来的数据. 解决方法: 可以使用data将父组件传递过来的数据拷贝一份存放起来,再修改拷贝的数据就可以了 / ...
- 关于React的父子组件通信等等
//==================================================此处为父子组件通信 1.子组件调用父组件: 父组件将子组件需要调用方法存入props属性内,子组 ...
随机推荐
- C++ 获取当前正在执行的函数的相关信息
(我的运行环境:win10x64+vs2015通过, 有的环境KUbuntu 8.04.1 x64 g++ 4.2.3也通过了)主要通过宏来实现:(注意,开头和结尾都是两个下划线) 1. __PRET ...
- 03-14_WLST配置现有的Domain
本文重点: WLST在线模式配置现有的domains. WLST离线模式配置现有的domains. 1.WLST在线模式配置现有的domains 由于和一个活动的domain进行交互, ...
- SQL alwayson 辅助接点查询统计信息“丢失”导致查询失败
ALWAYSON 出现以下情况已经2次了,记录下: DBCC 执行完毕.如果 DBCC 输出了错误信息,请与系统管理员联系. 消息 2767,级别 16,状态 1,过程 sp_table_statis ...
- webservice偶尔报黄页,解决方案
在system.web节点里加以下代码 <webServices> <protocols> <add name="HttpSoa ...
- scp 实现远程异地备份
1.先做好脚本 2.再使用crontab 定时执行计划任务 0 1 * * * /usr/bin/expect /root/script/scpautodown.sh #执行,也可先定义环境变量 0 ...
- Emacs中使用shell(调出terminal)
在Emacs中使用shell(调出terminal) 方法: M-x eshell 注意:不能使用 M-x shell,这样调用的是 cmd命令,一些命令无法使用
- bash的内置字符串处理工具
bash内置字符串处理工具: 1.字符串切片: ${var:offset:number} 取字符串的子串: ${var: -length} 取字符串的最右侧的length个字符.注意:冒号右侧必须有 ...
- Hive-1.2.1_01_安装部署
前言:该文章是基于 Hadoop2.7.6_01_部署 进行的. 1. Hive基本概念 1.1. 什么是Hive Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库 ...
- kafka的Java客户端示例代码(kafka_2.11-0.8.2.2)
1.使用Producer API发送消息到Kafka 从版本0.9开始被KafkaProducer替代. HelloWorldProducer.java package cn.ljh.kafka.ka ...
- nginx防攻击的简单配置
主要通过两方案来做防护,一是nginx自带模块限制请求连接数和并发数:二是筛选IP加入黑名单: 1.并发数和连接数控制的配置 nginx http配置: #请求数量控制,每秒20个 ...