内容简介:你可以放心地在 JSX 当中使用用户输入,React DOM 在渲染之前默认会Babel 转译器会把 JSX 转换成一个名为 React.createElement() 的方法调用。等价
你可以放心地在 JSX 当中使用用户输入,React DOM 在渲染之前默认会 过滤 所有传入的值。它可以确保你的应用不会被注入攻击。 所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(跨站脚本) 攻击。
JSX 代表 Objects
Babel 转译器会把 JSX 转换成一个名为 React.createElement() 的方法调用。
const element = ( <h1 className="greeting"> Hello, world! </h1> ); 复制代码
等价
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' ); 复制代码
React.createElement() 这个方法首先会进行一些避免bug的检查,之后会返回一个类似下面例子的对象:
// 注意: 以下示例是简化过的(不代表在 React 源码中是这样) const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world' } }; 复制代码
这样的对象被称为 “React 元素”。它代表所有你在屏幕上看到的东西。 React 通过读取这些对象来构建 DOM 并保持数据内容一致。
元素渲染
与浏览器的 DOM 元素不同, React 当中的元素事实上是普通的对象 ,(也就是html标签+内容)React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。
const element = <h1>hello</h1>; 复制代码
要将React元素渲染到根DOM节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:
const element = <h1>hello</h1>; ReactDOM.render(element,document.getElementById('root')); 复制代码
更新元素渲染
React 元素都是不可变的。当元素被创建之后,你是无法改变其内容或属性的.一个元素就好像是动画里的一帧,它代表应用界面在某一时间点的样子。
组件 & Props
组件可以将UI切分成一些独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件。
组件从概念上看就像是函数,它可以接收任意的输入值(称之为“props”),并返回一个需要在页面上展示的React元素。
函数/es6类 定义组件
函数
function Welcome(props) { return <h1>Hello, {props.name}</h1>; } 复制代码
es6类继承
class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } 复制代码
组件渲染
React元素也可以是用户自定义的组件: 例如,这段代码会在页面上渲染出”Hello,Sara”:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; } const element = <Welcome name="Sara" />; ReactDOM.render( element, document.getElementById('root') ); 复制代码
过程:1、我们对<Welcome name="Sara" ,/>元素调用了ReactDOM.render()方法。
2、React将{name: 'Sara'}作为props传入并调用Welcome组件。
3、Welcome组件将<h1,>Hello, Sara</h1,>元素作为结果返回。
4、React DOM将DOM更新为<h1,>Hello, Sara</h1,>。
组件名称必须以大写字母开头。
例如,<div,> 表示一个DOM标签,但 <Welcome,> 表示一个组件,并且在使用该组件时你必须定义或引入它。
组件的返回值只能有一个根元素。这也是我们要用一个<div,>来包裹所有<Welcome ,/>元素的原因。
State & 生命周期
状态(state)
定义为 类 的组件有一些额外的特性。局部状态就是如此: 只能用于类 的一个功能。
状态与属性十分相似,但是状态是私有的,完全受控于当前组件。
将函数转换为类
你可以通过5个步骤将函数组件 Clock 转换为类
1、创建一个名称扩展为 React.Component 的ES6 类
2、创建一个叫做render()的空方法
3、将函数体移动到 render() 方法中
4、在 render() 方法中,使用 this.props 替换 props
5、删除剩余的空函数声明
class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.date.toLocaleTimeString()}.</h2> </div> ); } } 复制代码
Clock 现在被定义为一个类而不只是一个函数
使用类就允许我们使用其它特性,例如局部状态、生命周期钩子
为一个类添加局部状态
我们会通 过3个步骤将 date 从属性移动到状态中 :
1、在 render() 方法中使用 this.state.date 替代 this.props.date
2.添加一个类构造函数来初始化状态 this.state
3.从 元素移除 date 属性: 代码如下
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') ); 复制代码
将生命周期方法添加到类中
我们可以在 组件类上 声明特殊的方法, 当组件挂载或卸载时 ,来运行一些代码:
componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } //当组件输出到 DOM 后会执行 componentDidMount() 钩子, //这是一个建立定时器的好地方: componentWillUnmount() { clearInterval(this.timerID); } //我们将在 componentWillUnmount()生命周期钩子中卸载计时器: 复制代码
最后,我们实现了每秒钟执行的 tick() 方法。
它将使用 this.setState() 来更新组件局部状态:
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount() { clearInterval(this.timerID); } !!!! tick() { this.setState({ date: new Date() }); }//setState() 来调度UI更新。 //通过调用 setState() ,React 知道状态已经改变, //并再次调用 render() 方法来确定屏幕上应当显示什么。 !!!! render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') ); 复制代码
让我们快速回顾一下发生了什么以及调用方法的顺序:
1、当 被传递给 ReactDOM.render() 时,React 调用 Clock 组件的构造函数。 由于 Clock 需要显示当前时间,所以使用包含当前时间的对象来初始化 this.state 。 我们稍后会更新此状态。
2.React 然后调用 Clock 组件的 render() 方法。这是 React 了解屏幕上应该显示什么内容,然后 React 更新 DOM 以匹配 Clock 的渲染输出。
3.当 Clock 的输出插入到 DOM 中时,React 调用 componentDidMount() 生命周期钩子。 在其中,Clock 组件要求浏览器设置一个定时器,每秒钟调用一次 tick()。
4.浏览器每秒钟调用 tick() 方法。 在其中,Clock 组件通过使用包含当前时间的对象调用 setState() 来调度UI更新。 通过调用 setState() ,React 知道状态已经改变,并再次调用 render() 方法来确定屏幕上应当显示什么。 这一次,render() 方法中的 this.state.date 将不同,所以渲染输出将包含更新的时间,并相应地更新DOM。
5.一旦Clock组件被从DOM中移除,React会调用componentWillUnmount()这个钩子函数,定时器也就会被清除。
正确地使用状态
关于 setState() 这里有三件事情需要知道
1.不要直接更新状态
// Wrong 错误!! this.state.comment = 'Hello'; 应当使用 setState(): // Correct this.setState({comment: 'Hello'}); 复制代码
构造函数是唯一能够初始化 this.state 的地方。
2.状态更新可能是异步的
因为 this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。
// Wrong this.setState({ counter: this.state.counter + this.props.increment, }); 复制代码
要修复它,请使用第二种形式的 setState() 来接受一个函数而不是一个对象。 该函数将接收先前的状态作为第一个参数, 将此次更新被应用时的props做为第二个参数:
// Correct this.setState((prevState, props) => ({ counter: prevState.counter + props.increment })); 复制代码
3、状态更新合并
数据自顶向下流动
父组件或子组件都不能知道某个组件是有状态还是无状态,并且它们不应该关心某组件是被定义为一个函数还是一个类。
这就是为什么状态通常被称为局部或封装。 除了拥有并设置它的组件外,其它组件不可访问。
事件处理
react和dom的很相似,但是有一些语法的不同
React事件绑定属性的命名采用驼峰式写法,而不是小写。
如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)eg::: 传统的 HTML:
<button onclick="activateLasers()"> Activate Lasers </button> 复制代码
React 中稍稍有点不同:
<button onClick={activateLasers}> Activate Lasers </button> 复制代码
使用 React 的时候 你不需要使用 addEventListener 为一个已创建的 DOM元素添加监听器。你仅仅需要在这个元素初始渲染的时候提供一个监听器。
表单
受控组件
使用”受控组件”,每个状态的改变都有一个与之相关的处理函数。这样就可以 直接修改或验证用户输入 。例如,我们如果想限制输入全部是大写字母,我们可以将handleChange 写为如下:
handleChange(event) { this.setState({value: event.target.value.toUpperCase()}); } 复制代码
textarea 标签
在React中,<textarea,>会用value属性来代替。这样的话,表单中的<textarea,> 非常类似于使用单行输入的表单:
class EssayForm extends React.Component { constructor(props) { super(props); this.state = { value: 'Please write an essay about your favorite DOM element.' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert('An essay was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <textarea value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); } } 复制代码
注意this.state.value是在构造函数中初始化,这样文本区域就能获取到其中的文本。
select 标签
请注意,Coconut选项最初由于selected属性是被选中的。在React中,并不使用之前的selected属性, 而在根select标签上用value属性来表示选中项 。这在受控组件中更为方便,因为你只需要在一个地方来更新组件。例如:
构造函数中 this.state = {value: 'coconut'}; 类中 handleChange(event) { this.setState({value: event.target.value}); } render return中 <select value={this.state.value} onChange={this.handleChange}> 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 利用Python3内置文档资源高效学习及官方中文文档
- MongoDB学习笔记:文档
- Apache Pig入门学习文档(一)
- Apache Pig入门学习文档(一)
- Openstack Swift学习(二):相关文档
- Apache Pig入门学习文档(一)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
网络营销实战密码
昝辉Zac / 电子工业出版社 / 2009.1 / 56.00元
本书是作者几年来网络营销实战的总结,与其他网络营销书籍最大不同之处是:只专注于实战,不谈理论。本书分三部分详细介绍了网络营销实用策略和技巧,并分析了大量实战案例。第一部分介绍市场与产品研究,包括用户、市场和竞争对手的调查;产品、目标市场的确定;价格策略;赢利模式等。第二部分讨论以网络营销为导向的网站设计,包括怎样在网站上卖东西、提高转化率,以及网站目标设定等。第三部分研究怎样给网站带来流量,详细讨......一起来看看 《网络营销实战密码》 这本书的介绍吧!