react(一)
1、es6的class、箭头函数 1)ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class Point { constructor(x,y) { this.x = x; this.y = y; } toString() { return ‘(‘ + this.x + ‘,‘ + this.y + ‘)‘; } } var p1 = new Point(1,1); console.log(p1.toString()); // (1,1) console.log(typeof Point,Point === Point.prototype.constructor); // function true 上面代码定义了一个“类”,可以看到里面有一个
上面代码表明,类的数据类型就是函数,类本身就指向构造函数。使用的时候,也是直接对类使用 构造函数的 class Point { constructor() { // ... } toString() { // ... } } // 等同于 Point.prototype = { constructor() {},toString() {} }; 类必须使用 var p1 = new Point(2,3); var p2 = new Point(3,2); p1.__proto__ === p2.__proto__; //true 上面代码中,
2)Class 可以通过 class ColorPoint extends Point {
}
上面代码定义了一个 class ColorPoint extends Point { constructor(x,y,color) { super(x,y); // 调用父类的constructor(x,y) this.color = color; } toString() { return this.color + ‘ ‘ + super.toString(); // 调用父类的toString() } } let cp = new ColorPoint(1,1,‘red‘); console.log(cp,cp.toString()); // ColorPoint {x: 1,y: 1,color: "red"} "red (1,1)" 子类必须在 如果子类没有定义 class ColorPoint extends Point { } // 等同于 class ColorPoint extends Point { constructor(...args) { super(...args); } } let cp = new ColorPoint(25,8,‘green‘); cp instanceof ColorPoint // true cp instanceof Point // true 上面代码中,子类ColorPoint实例对象 ?3)ES6 允许使用“箭头”( var f = v => v; // 等同于 var f = function (v) { return v; }; 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。 var f = () => 5; // 等同于 var f = function () { return 5 }; var sum = (num1,num2) => num1 + num2; // 等同于 var sum = function(num1,num2) { return num1 + num2; }; 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用 var sum = (num1,num2) => { return num1 + num2; } 由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。 // 报错 let getTempItem = id => { id: id,name: "Temp" }; // 不报错 let getTempItem = id => ({ id: id,name: "Temp" }); ? 2、react 参考:http://www.voidcn.com/article/p-rkowmlmt-bnx.html http://www.css88.com/react/docs/try-react.html
参考:http://www.css88.com/react/docs/cdn-links.html <div id="root"></div> <!-- react.js 是 React 的核心库,react-dom.js 是提供与 DOM 相关的功能 --> <script crossorigin src="https://unpkg.com/[email?protected]/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/[email?protected]/umd/react-dom.development.js"></script> <!-- 上面的版本只适合开发环境,不适合生产环境。下面为压缩优化版本 <script crossorigin src="https://unpkg.com/[email?protected]/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/[email?protected]/umd/react-dom.production.min.js"></script> --> <!-- babel:将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成 --> <script src="https://unpkg.com/[email?protected]/babel.min.js"></script> <!-- <script> Uncaught SyntaxError: Unexpected token <--> <!-- 控制台有警告:You are using the in-browser Babel transformer. Be sure to precompile your scripts for production 网页中实时将ES6代码转为ES5,对性能会有影响。生产环境需要加载已经转码完成的脚本 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel" --> <script type="text/babel"> const element = <h1>Hello,world</h1>; ReactDOM.render( element,document.getElementById(‘root‘) ); </script> 浏览器渲染结果: a)crossorigin(实现更好的错误处理体验) 引入跨域的脚本(比如用了 apis.google.com 上的库文件),如果这个脚本有错误,因为浏览器的限制(根本原因是协议的规定),是拿不到错误信息的。当本地尝试使用? b)更通用格式?UMD(Universal Module Definition)-希望提供一个前后端跨平台的解决方案 ?UMD的实现很简单,先判断是否支持NodeJS模块格式(exports是否存在),存在则使用NodeJS模块格式。再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。前两个都不存在,则将模块公开的全局(window或global)。 c)ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。
参考:https://segmentfault.com/q/1010000003877594/a-1020000003878406 JavaScrip 的一种扩展语法,推荐在 React 中使用这种语法来描述 UI 信息。React为了代码的可读性、更方便地创建虚拟DOM等原因,加入了一些类似XML的语法扩展。JSX是可选的,对于使用 React 而言不是必须的。 JSX 的基本语法规则:遇到 HTML 标签(以? JSX代码并不能直接运行,需要将它编译成正常的JavaScript表达式才能运行,jsxTransformer.js就是这一编译器的角色。React官方博客在2015年6月发布了一篇文章,声明用于JSX语法解析的编译器JSTransform已经过期,不再维护,React JS和React Native已经全部采用第三方Babel的JSX编译器实现。Babel作为专门的JavaScript语法编译工具,提供了更为强大的功能。 function formatName(user) { return user.firstName + ‘ ‘ + user.lastName; } const user = { firstName: ‘Harper‘,lastName: ‘Perez‘ }; const title = ‘我是h1‘; const element = ( <div> <h1 title={title}>Hello,{formatName(user)}!</h1> <img className="img" src="http://img2.imgtn.bdimg.com/it/u=3723784612,2573513060&fm=200&gp=0.jpg"/> </div> ); ReactDOM.render( element,document.getElementById(‘root‘) ); 为便于阅读,我们将 JSX 分割成多行。我们推荐使用括号将 JSX 包裹起来,虽然这不是必须的,但这样做可以避免分号自动插入的陷阱。 在属性中嵌入 JavaScript 表达式时,不要使用引号来包裹大括号。否则,JSX 将该属性视为字符串字面量而不是表达式。对于字符串值你应该使用引号,对于表达式你应该使用大括号,但两者不能同时用于同一属性。 jsx里的标签都应该闭合。 比起 HTML , JSX 更接近于 JavaScript , 所以 React DOM 使用驼峰属性命名约定,而不是HTML属性名称。例如, render()函数中返回的所有元素需要包裹在一个"根"元素里面。
Props 是只读的:无论你用函数或类的方法来声明组件,它都无法修改其自身 props. 1)函数式组件 所有的React组件都有一个 <div id="root"></div> 以下代码在页面上渲染 “Hello,Sara”? // 接收一个 props 参数,并返回一个 React 元素 function Welcome(props) { return <h1>Hello,{props.name}</h1>; } // 用户定义组件(Welcome 组件)将 JSX 属性以一个单独对象的形式传递给相应的组件,我们将其称为 “props” 对象 const element = <Welcome name="Sara" />; ReactDOM.render( element,document.getElementById(‘root‘) ); 组件名称总是以大写字母开始,否则会报错;组件可以在它们的输出中引用其它组件。 function Welcome(props) { return <h1>Hello,{props.name}</h1>; } function App() { return ( <div> <Welcome name="Sara" /> <Welcome name="Cahal" /> <Welcome name="Edite" /> </div> ); } ReactDOM.render( <App />,document.getElementById(‘root‘) ); 2)提取组件 不要害怕把一个组件分为多个更小的组件。提取组件可能看起来是一个繁琐的工作,但是在大型的 Apps 中可以回报给我们的是大量的可复用组件。一个好的经验准则是如果你 UI 的一部分需要用多次 ,或者本身足够复杂,最好的做法是使其成为可复用组件。 3)类组件 类组件允许我们在其中添加本地状态和生命周期钩子 class Clock extends React.Component { // 添加一个类构造函数初始化this.state constructor(props) { super(props); this.state = {date: new Date()}; } // 挂载—组件输出被渲染到 DOM 之后运行(设置定时器) componentDidMount() { // 如果需要存储一些不用于视觉输出的内容,则可以手动向类中添加额外的字段,如下面的timerID // 如果在 render() 方法中没有被引用,它不应该出现在 state 中 this.timerID = setInterval( () => this.tick(),1000 ); } // 卸载—DOM 被销毁时运行(清除计时器) componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); // 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‘) ); 分析:
正确地使用 State(状态) ?a)不要直接修改 state。 例如,这样将不会重新渲染一个组件:this.state.date = new Date(); 用? 唯一可以分配? b)state更新可能是异步的 React 为了优化性能,有可能会将多个? class Clock extends React.Component { // 添加一个类构造函数初始化this.state constructor(props) { 因为? // 错误 this.setState({ counter: this.state.counter + this.props.increment,}); 要弥补这个问题,使用另一种 setState() 的形式,它接受一个函数而不是一个对象。这个函数将接收前一个状态作为第一个参数,应用更新时的 props 作为第二个参数。 // 正确 this.setState((prevState,props) => ({ counter: prevState.counter + props.increment })); ?c)state更新会被合并 当你调用? 4)数据向下流动 一个组件可以选择将 state(状态) 向下传递,作为其子组件的 props(属性)。这通常称为一个“从上到下”,或者“单向”的数据流。任何 state始终由某个特定组件所有,并且从该 state导出的任何数据 或 UI 只能影响树中 “下方” 的组件。 class Clock extends React.Component { // ... render() { return ( <div> <FormattedDate date={this.state.date}/> </div> ); } } function FormattedDate(props) { return <h2>It is {props.date.toLocaleTimeString()}.</h2> } ReactDOM.render( <Clock />,document.getElementById(‘root‘) ); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |