React入门笔记(一) — 深入理解JSX

《一》、理解JSX

  JSXJavascrpt XML— — 一种在React组件内部构建标签的类XML语法。
  JSX并不是新语言,也没有改变JavaScript的语法,只是一种基于ECMAScript的新特性,一种定义带属性树结构(DOM结构)的语法
  React 可以不使用 JSX 来编写组件,但是使用 JSX 可以让代码可读性更高、语义更清晰、对 React 元素进行抽象等等。

一、使用JSX好处

  1、允许使用熟悉的语法来定义HTML元素树  2、提供了更加语义化且易懂的标签
  3、程序结构更容易被直观化  4、抽象了React Element的创建过程
  5、可以随时掌控HTML标签以及生成这些标签的代码  63、是原生Javascript

使用JSX和不使用JSX的代码对比如下:

//开闭标签,在构建复杂的树形结构时,比函数调用和对象字面量更易读
//#使用JSX
<div className="red">Children Text</div>;
<MyCounter count={3 + 5} />;
// 此处给一个js对象设置"scores"属性
var gameScores = {
  player1: 2,
  player2: 5
};
<DashboardUnit data-index="2">
  <h1>Scores</h1>
  <Scoreboard className="results" scores={gameScores} />
</DashboardUnit>;

//#不使用JSX
React.createElement("div", { className: "red" }, "Children Text");
React.createElement(MyCounter, { count: 3 + 5 });

React.createElement(
  DashboardUnit,
  { "data-index": "2" },
  React.createElement("h1", null, "Scores"),
  React.createElement(Scoreboard, { className: "results", scores: gameScores })
);
二、JSX 语法

【注意】 JSX代码需经babel 编译成javscript,目前主流浏览器才能正常识别,即在head中需添加:

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>

React还需依赖的另外2个文件:react.js 是 React 的核心库,react-dom.js 是提供与 DOM 相关的功能,
并将JSX代码放在<script type='text/babel'></script>中编写

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

【推广】上面必需核心库找不到的话,可以上本人github下载:https://github.com/mqy1023/react-basejs


  JSXHTMLJavaScript混写的语法,当遇到<JSX就当HTML解析,遇到 { 就当JavaScript解析。

var names = ['Alice', 'Emily', 'Kate'];
ReactDOM.render(
  <div>
  {
    names.map(function (name) {
      return <div>Hello, {name}!</div>
    })
  }
  </div>,
  document.getElementById('example')
);


理解Array.prototype.map,返回一个新的数组

var friends = ['Jake Lingwall', 'Murphy Randall', 'Merrick Christensen'];
var listItems = friends.map(function(friend){
  return "<li> " + friend + "</li>";
});
console.log(listItems); // ["<li> Jake Lingwall</li>", "<li> Murphy Randall</li>", "<li> Merrick Christensen</li>"];

  JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员

// arr变量是一个数组,结果 JSX 会把它的所有成员,添加到模板
var arr = [
  <h1>Hello world!</h1>,
  <h2>React is awesome</h2>,
];
ReactDOM.render(
  <div>{arr}</div>,
  document.getElementById('example')
);


  在React中,一个组件的HTML标签与生成这些标签的代码内在地紧密联系在一起。这意味和我们可以轻松地利用Javascript强大魔力
  1、使用三目运算符

render: function() {
   return <div className={this.state.isComplete ? 'is-complete' : ''}>...</div>;
}

  2、使用变量/函数

getIsComplete: function() {
   return this.state.isComplete ? 'is-complete' : '';
},
render: function() {
   var isComplete = this.getIsComplete();
   return <div className={isComplete}>...</div>;

   //或者直接返回函数
   return <div className={this.getIsComplete()}>...</div>;
}

  3、使用逻辑与(&&)或者逻辑或( || )运算符
    由于对于null或false值React不会输出任何内容,因此可以使用一个后面跟随了期望字符串的布尔值来实现条件判断。如果这个布尔值为true,后续字符串会被使用

render: function() {
   return <div className={this.state.isComplete && 'is-complete'}>...</div>;
}

    逻辑或,this.props.name为空时,className值等于is-complete

render: function() {
   return <div className={this.props.name || 'is-complete'}>...</div>;
}

  4、函数调用

var HelloWorld = React.createClass({
    render: function () {
        return <p>Hello, {(function (obj) { 
            return obj.props.name ? obj.props.name : "World";
        })(this)}</p>
    }
});
三、创建并渲染组件
//1、React.createClass 是用来创建一个组件
var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }
});
//2、ReactDOM.render渲染组件
ReactDOM.render(
  <HelloMessage name="John" />,
  document.getElementById('example')
);
《二》、JSX和HTML不同点
一、渲染HTML标签和React组件

  React.render方法可以渲染HTML结构,也可以渲染React组件。
    1、渲染HTML标签,声明变量采用首字母小写

var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.body);

    2、渲染React组件,声明变量采用首字母大写

var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.body);
二、非DOM属性

1、键(key
  key是一个可选的唯一标识符,当两个已经在于DOM中的组件交换位置时,React能够匹配对应的key并进行相应的移动,且不需要完全重新渲染DOM,提供渲染性能

2、引用(ref
  ref允许父组件在render方法之外保持对子组件的一个引用。在JSX中,你可以通过属性中设置期望的引用名来定义一个引用。

render: function() {
   return <div> 
            <input ref="myInput" ...> </input>
          </div>
    );
}

  然后你可以在组件的任何地方使用this.refs.myInput获取这个引用了。通过引用获取到的这个对象被称为支持实例。它并不是真的DOM,而是React在需要时用来创建DOM的一个描述对象。你可以使用this.refs.myInput.getDOMNode()访问真实的DOM节点。

3、设置原始的HTML
  比如我们有一些内容是用户输入的富文本,希望展示相应的样式

var content='<strong>content</strong>';
ReactDOM.render(
    <div>{content}</div>,
    document.body
);

结果页面直接输出内容了:
这里写图片描述
React默认会进行HTML的转义,避免XSS攻击,如果要不转义,可以这么写:

ReactDOM.render(
    <div dangerouslySetInnerHTML={{__html: "<strong>content</strong>"}}></div>,
    document.body
);
三、事件

  在所有的浏览器中,事件名已经被规范化并统一用onXXX驼峰形式表示

var BannerAd = React.createClass({
    handleClick: function(event) {
        //...
    },
    render: function() {
       return <div onClick={this.handleClick}>Click Me!</div>;
    }
})

【注意】 React自动绑定了组件所有方法的作用域,因此你不需要手动绑定

handleClick: function(event) {...},
render: function() {
   //反模式 ————在React中手动给组件实例绑定
   //函数作用域是没有必要的
   return <div onClick={this.handleClick.bind(this)}>...</div>;
}
四、特殊属性

  由于JSX会转换为原生的Javascript函数,因此有一些关键词我们是不能用的——如classfor,对应JSX中属性写成classNamehtmlFor

//#使用JSX
ReactDOM.render(
    <label className="xxx" htmlFor="input">content</label>,
    document.getElementById('example')
);
//#不使用JSX
ReactDOM.render(
    React.createElement('label', {className: 'xxx', htmlFor: 'input'}, 'content'),
    document.getElementById('example')
);
五、style样式

  React把所有的内联样式都规范化为驼峰形式,与JavascriptDOMsytle属性一致。第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象。

React.render(
    <div style={{color:'red'}}>
        xxxxx
    </div>,
    document.body
);
////////////////////////////
var style = {
    color:'red',
    borderColor: '#999'
}
ReactDOM.render(<div style={style}>xxxxx</div>, document.body);
六、注释

JSX本质就是Javascript,因此你可以在标签内添加原生的javascript注释。

  • 注释两种形式
    • 当作一个元素的子节点
    • 内联在元素的属性中
var content = (
  <Nav>
    {/* 一般注释, 用 {} 包围 */}
    <Person
      /* 多
         行
         注释 */
      name={window.isLoggedIn ? window.name : ''} // 行尾注释
    />
  </Nav>
);
《三》、JSX延伸属性
一、不要改变props

  如果提前就知道了组件的属性的话,写起来很容易。例如component组件有两个动态的属性foo和bar:

var component = <Component foo={x} bar={y} />;

  而实际上,有些属性可能是后续添加的,我们没办法一开始就确定,我们可能会写出下面不好的代码:

var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad

  这样写是错误的,因为我们手动直接添加的属性React后续没办法检查到属性类型错误,也就是说,当我们手动添加的属性发生类型错误时,在控制台是看不到错误信息的。

  在React的设定中,初始化完props后,props是不可变的。改变props会引起无法想象的后果。

二、延伸属性

  为了解决这个问题,React引入了属性延伸

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;

  当需要拓展我们的属性的时候,定义个一个属性对象,并通过{...props}的方式引入,React会帮我们拷贝到组件的props属性中。重要的是—这个过程是由React操控的,不是手动添赋值的属性。

  需要覆盖的时候可以这样写:

var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
《四》、JSX 陷阱
一、自定义HTML属性

  如果往原生 HTML 元素里传入 HTML 规范里不存在的属性,React 不会显示它们。

ReactDOM.render(
    <div dd='xxx'>content</div>,
    document.body
);

如果需要使用自定义属性,要加 data- 前缀。

ReactDOM.render(
    <div data-dd='xxx' aria-dd='xxx'>content</div>,
    document.body
);

二、组件render渲染函数中return注意点
如果return和JSX语句开头在同一行时,不需要括号;否则要括号包裹

//正确写法1
var HelloMessage = React.createClass({
  render: function() {
    return <h1>
        Hello {this.props.name}</h1>;
  }
});
//正确写法2
render: function() {
    return <h1>Hello {this.props.name}</h1>;
}
//正确写法3
render: function() {
    return (
        <h1>Hello {this.props.name}</h1>);
}

//错误写法
render: function() {
    return 
        <h1>Hello {this.props.name}</h1>;
}



参考链接
1、《React学习笔记—JSX》https://segmentfault.com/a/1190000002646155
2、《React引领未来的用户界面开发框架》
3、http://facebook.github.io/react/docs/jsx-in-depth.html
4、http://www.jikexueyuan.com/course/969_3.html?ss=1
5、http://buildwithreact.com/tutorial/jsx

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值