-
-
Notifications
You must be signed in to change notification settings - Fork 65
Description
JSX
JSX是React的核心组成部分,它使用XML标记的方式去直接声明界面,界面组件之间可以互相嵌套。可以理解为在JS中编写与XML类似的语言,一种定义带属性树结构(DOM结构)的语法,它的目的不是要在浏览器或者引擎中实现,它的目的是通过各种编译器将这些标记编译成标准的JS语言。
虽然你可以完全不使用JSX语法,只使用JS语法,但还是推荐使用JSX,可以定义包含属性的树状结构的语法,类似HTML标签那样的使用,而且更便于代码的阅读。
使用JSX语法后,你必须要引入babel的JSX解析器,把JSX转化成JS语法,这个工作会由babel自动完成。同时引入babel后,你就可以使用新的es6语法,babel会帮你把es6语法转化成es5语法,兼容更多的浏览器。
import React from 'react';
class PageB extends React.Component {
constructor(props) {
super(props);
// 设置 initial state
this.state = {
};
}
componentDidMount() {
}
render() {
return (
<div>
<p>PageB</p>
</div>
)
}
}
export default PageB;在这个简单的例子中,看不出来有任何jsx语法的地方,当其中<div><p>PageB</p></div>就是使用到了jsx语法。HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它允许 HTML 与 JavaScript 的混写。
组件
- 在react中通常约定组件类的第一个字母必须大写,html标签都是小写。
- 组件类只能包含一个顶层标签,否则会报错
样式
class属性需要写成 className,for属性需要写成 htmlFor,这是因为class和for是JavaScript的保留字
pageB.jsx
import React from 'react';
//引入外部样式
import './pageB.css';
// React component
class PageB extends React.Component {
constructor(props) {
super(props);
// 设置 initial state
this.state = {
};
}
componentDidMount() {
}
render() {
return (
<div>
<p className="pageb-p">PageB</p>
</div>
)
}
}
export default PageB;pageB.css
.pageb-p{
font-size: 40px;
}直接在标签上使用style属性时,要写成style={{}}是两个大括号,外层大括号是告知jsx这里是js语法,和真实DOM不同的是,属性值不能是字符串而必须为对象,需要注意的是属性名同样需要驼峰命名法。即margin-top要写成marginTop
比如以下这个render
render() {
return(
<div style={{border: '1px solid blue', padding: '20px', marginBottom: '20px'}}>
{/* 样式通过style={{}}的方法定义,里面的对象的属性值要用驼峰的写法 */}
<p>{this.state.text}</p>
<p>{this.props.name}</p>
<input onChange={this.handleSubmit} />
</div>
)
}state和props
- 组件免不了要与用户互动,React 将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI。
- getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。
ES5设置state和props
var HelloMessage = React.createClass({
getDefaultProps: function() {
return {
name: 'Wscats'
};
},
getInitialState: function() {
return {
skill: 'PS'
}
},
render: function() {
return <h1>Hello {this.props.name}{this.state.skill}</h1>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);ES6设置state和props
class HelloMessage extends React.Component{
constructor(props){
super(props);
this.state = {
skill: 'PS'
}
}
render(){
return <h1>Hello {this.props.name}{this.state.skill}</h1>
}
}
HelloMessage.defaultProps = {
name: 'Wscats'
}class Hello extends React.Component {
this.state = this.getInitialState();
getInitialState() {
return {name: "Wscats"};
}
render() {
return <div>Hello {this.state.name}</div>;
}
}获取真实的DOM节点
组件并不是真实的DOM节点,而是存在于内存之中的一种数据结构,叫做虚拟DOM(virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。
有时需要从组件获取真实DOM的节点,这时就要用到ref属性。
import React from 'react';
class PageB extends React.Component {
constructor(props) {
super(props);
// 设置 initial state
this.state = {
};
}
componentDidMount() {
//等到虚拟DOM插入文档以后,即componentDidMount生命周期后才能使用这个属性
this.refs.nihao.style.color = "red"
}
render() {
return (
<div>
{/*通过ref来获取真是DOM节点*/}
<p >PageC</p>
<p ref="nihao">{(function(){
return "你好"
})()}</p>
</div>
)
}
}
export default PageB;为了获取真是DOM节点,html元素必须有一个ref属性,然后this.refs.[refName]就会返回这个真实的 DOM节点。需要注意的是,由于this.refs.[refName]属性获取的是真实DOM,所以必须等到虚拟DOM插入文档以后,才能使用这个属性,否则会报错。
求值表达式
要使用JavaScript表达式作为属性值,只需把这个表达式用一对大括号( { } )包起来,不要用引号 ( " " )。
在编写JSX时,在{ }中不能使用语句(if语句、for语句等等),但可以使用求值表达式,这本身与JSX没有多大关系,是JS中的特性,它是会返回值的表达式。我们不能直接使用语句,但可以把语句包裹在函数求值表达式中运用。
条件判断的写法
你没法在JSX中使用if-else语句,因为JSX只是函数调用和对象创建的语法糖。在{ }中使用,是不合法的JS代码,不过可以采用三元操作表达式
可以使用比较运算符“ || ”来书写,如果左边的值为真,则直接返回左边的值,否则返回右边的值,与if的效果相同。
import React from 'react';
import './pageB.css';
class PageB extends React.Component {
constructor(props) {
super(props);
// 设置 initial state
this.state = {
name:""
};
}
componentDidMount() {
var self = this;
setTimeout(function(){
self.setState({
name:"我是谁,我在哪里?"
})
},1000)
}
render() {
return (
<div>
<p>PageB</p>
{/*三元操作表达式*/}
<p className="pageb-p">1.三元操作</p>
<p>{this.state.name?this.state.name:"加载中"}</p>
{/*运算符||*/}
<p className="pageb-p">2.运算符||</p>
<p>{this.state.name||"加载中"}</p>
</div>
)
}
}
export default PageB;函数表达式
函数的语法可以这样,注意要用自执行,并且要传入this,和return出结果
<p>{(function(){
return "Wscats"
})()}</p>
<p>{(function(self){
console.log(self.state.name)
return self.state.name;
})(this)}</p>
<p>{(function(self){
{/*v-if*/}
if(self.state.bool){
return "假";
}else{
return "真";
}
})(this)}</p>
<p>
{/*过滤器*/}
{this.ed(this.state.name)}
</p>过滤器的函数,接受this.state.name数据并处理再输出
//记得在this.state改变this.ed = this.ed.bind(this);
ed(data) {
//模拟过滤器
console.log(data)
return data + "ed"
}组件的生命周期
- Mounting:已插入真实 DOM
- Updating:正在被重新渲染
- Unmounting:已移出真实 DOM
注释
JSX里添加注释很容易;它们只是 JS 表达式而已。你只需要在一个标签的子节点内(非最外层)小心地用{}包围要注释的部分。
{/* 一般注释, 用 {} 包围 */}注意:
- 在标签内部的注释需要花括号
- 在标签外的的注释不能使用花括号
ReactDOM.render(
/*注释 */
<h1>Wscars{/*注释*/}</h1>,
document.getElementById('example')
);