原文地址:
http://blog.csdn.net/crystal6918/article/details/74942283?locationNum=2&fps=1
上一篇:
一、JSX
是js的一种语法扩展,在React中用于描述UI
1)在JSX中使用{}嵌入任何js表达式
2)多行JSX最好使用括号wrap
3)编译后,JSX表达式成为常规的JavaScript对象。因此可以在if或者for循环中使用,或者复制给其他的变量、从函数中返回等
4)在JSX中,class为className
5)JSX可以防止注入攻击。
在JSX中包含用户输入是安全的,因为默认情况下ReactDOM在渲染JSX之前会将JSX中嵌入的值进行转义,有助于防御XSS攻击。
6)Babel将JSX编译成对React.createElement()的调用,最终会生成一个描述元素属性的object。该object就是React元素,React会读取这些object并最终构建为DOM
二、渲染
创建React元素的代价很低,React DOM负责根据React元素来更新DOM
ReactDOM.render(element, document.getElementById('id'))
三、组件
1)最简单的定义组件的方法就是定义一个函数:接受props为参数、返回一个JSX
2)使用class来定义一个组件:
继承React.Component
render()用于返回JSX
constructor()是继承了component基类,必须调用基类的constructor,并传入props:super(props)
初始化state
3)组件名称首字母大写
4)组件必须只返回一个根元素,一般用一个div来对内部元素进行包裹
5)函数式组件或者组件的render方法返回null,则此组件不会被渲染
四、props
父组件传递给子组件的数据:组件永远不能修改props,是只读的
五:state
setState()方法由父类Component所提供。当我们调用这个函数时,React.js会更新组件的状态state,并且重新调用render方法,然后再把render方法所渲染的最新的内容显示到页面上。
setState异步性
当调用setState时,React.js并不会马上修改state。而是把这个对象放到一个更新队伍里面,稍后才会从队列中把新的状态提取出来合并到state当中,然后再触发组件更新。
所以不能依赖它们的值去计算下一个状态的state,例如:
this.setStistate({ count: this.state.count +1})
而应该用上setState的第二种使用方式,接受一个函数作为参数。React.js会把一个setState的结果传入这个函数,就可以使用该结果进行运算、操作,然后返回一个队形作为更新state的对象:
this.setState((prevState) => {
return { count: prevState.count + 1 }
})
自上而下
state只被组件自己拥有,要想传递给其他的组件(子组件),就要使用props向下传递。
state与props的区别
1)props是父组件传递进来的数据,是只读的
2)state是组件自己维护的状态,是可变的
共同点
二者的变化都会触发组件的重新渲染
六、处理事件
1)React事件名使用驼峰命名法,而不是DOM中的小写形式
2)在JSX中为事件属性传入一个函数,而不是一个字符串。例如:
<button onClick={activeLasers}>
Activate Lasers
</button>
3)不能通过返回false来取消默认行为,必须在事件处理函数中显式调用preventDafault。
4)当使用class来定义组件的时候,一个常用的模式就是定义class的放大来处理事件:
class Toggle extends React.Component {
constructor (props) {
super(props);
this.state = {isToggleOn:true};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState (prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick} >
{this.state.isToggleOn ? 'ON' : 'OFF' }
</button>
);
}
}
1、在元素中使用click事件定义处理函数:onClick={this.handleClick},即class中的handleClick方法
2、早constructor的初始化工作中要注意为事件处理函数绑定this。在js中,class的方法并不默认绑定this,因此要自己强制也可以使用箭头函数来达到同样的目的:
class LoggingButton extends React.Component {
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick} >
Click me
</button>
);
}
}
七、列表
1)一般使用map()函数来遍历一个数组并生成对应的React元素:
const listItems = numbers.map((number) =>
<li>{number}</li>
);
可以使用{}包含一个元素列表
ReactDOM.render (
<ul>{listItems}</ul>
document.getElementById('root')
);
八、key属性
最好为每一个列表中的元素分配一个key属性。
key属性帮助React识别哪些项被修改了,被添加了或者被移除了。
1)不要求key属性在全局唯一,只要在兄弟元素中唯一即可
2)key属性对人React来说是一个重要信息,但是不会传递给你的组件。如果在组件中需要同一个值,需要自己使用另一个prop属性去传递
九、虚拟DOM
在React中,组件render方法得到的结果并不是真正的DOM节点,而是纯粹的js对象,用于描述DOM节点,我们称之为虚拟节点
React之所以比直接操作DOM的JS库快,原因就是在渲染是,React会把组件当前的虚拟DOM结构和前一次的虚拟DOM结构做比较,只有存在差异性,React才会把差异的内容同步到实体DOM上。
React速度快的原因,还有一个是它出色的Diff算法。标准的比较两棵树的Diff算法的时间复杂是O(n3)。
十、refs
ref属性用于获取组件的引用,这里子组件必须是一个React component的实例或者一个DOM元素
ref的应用场景一般是想要直接调用一个组件实例的方法,而不是通过传递新的props来时组件重新渲染。
例如使某个input元素获得焦点:
class AutoFocusTextInput extends React.Component {
componentDidMount() {
this.textInput.focus();
}
render() {
return (
<input ref={(input) => this.textInput = input} />
)
}
}
在这里我们给input元素加了一个ref属性,这是属性值是一个函数。当input元素在页面上挂载完成以后,React.js就会调用这个函数,并且把这个挂载以后的DOM节点传给这个函数。在函数中我们把这个DOM元素设置为组件实例的一个属性,这样以后我们就可以通过this.input获取到这个DOM元素。
不能在函数式组件中使用refs,因为它们没有实例
但是可以在函数式组件内部的DOM元素或者class组件上使用。
十一、props.children
我们可以在组件标签中编写内嵌的结构,就像普通的HTML标签一样
<Card>
<h2>React.js</h2>
<div>开源</div>
订阅:<input />
<Card>
在父组件中通过props。children获得嵌套在组件内部的JSX结构:
class Card extends Component{
render() {
return (
<div className='card'>
<div className='card-content'>
{this.props.children}
</div>
</div>
)
}
}