jsx的本质
jsx语法
1、所有html标签他都支持 <div></div>
2、大括号里面可以引入js变量 或者 表达式 {name || ''}
3、可以做判断 {show ? '' : ''}
4、可以循环 {list.map(item=>{ return <li>{item}</li>})}
5、样式 style={{fontSize:'40px'}}
jsx解析成js
jsx语法根本无法被浏览器解析,比如大括号的那种。像vue中的v-if,v-model等等,也无法直接浏览器运行。那么它如何在浏览器运行。最终都是转化为js运行的。
import React from 'react'; import Todo from './components/todo/index' function App() { return ( <div> <Todo/> </div> ); } export default App;
看这段代码,其他都用了,但是import React,这个 React 没用。但是要import进来,去掉之后肯定报错。报错了肯定是用了。在jsx转化为js的时候用到了React。去掉后会找不到,
看jsx的解析过程,先需要React.createElement去创建标签,第一个是标签名,第二个是属性,第三个,第四个,,,后面都是子元素。这个跟vdom里面的h函数非常像。跟vue中的_c函数也很像。
render() { const list = this.props.data; return ( <ul> { list.map((item,index)=>{ return <li key={index}>{item}</li> }) } </ul> ) } function render() { const list = this.props.data; return React.createElement( 'ul', null, list.map((item,index)=>{ return React.createElement( 'li', {key: index}, item ) }) ) }
这个就是jsx解析,命中了jsx的第二种用法,第三个是数组
所以jsx其实是语法糖,开发环境会将jsx编译成js代码,jsx的写法大大降低了学习成本和编码工作量,同时,jsx也会增加debug成本
独立的标准
jsx是React引入的,但不是React独有的。React已经将它作为独立标准开放,其他项目也可用。React.createElement是可以自定义修改的。标准化的前提是本身功能已经完备,和其他标准兼容和扩展性没问题
新建一个文件夹,然后npm init -y。然后新建一个文件叫demo.jsx
class Input extends Component { render(){ return ( <div> <input value={this.state.title} onChange={this.changeHandle.bind(this)} /> <button onClick={this.clickHandle.bind(this)}>submit</button> </div> ) } }
全局安装babel
sudo npm i babel -g (一般都安装过了)
然后安装jsx插件
npm install -save-dev babel-plugin-transform-react-jsx
然后创建.babelrc文件
{ "plugins": ["transform-react-jsx"] }
配置完之后就可以运行了
babel --plugins transform-react-jsx demo.jsx
然后编译出的js代码长这样
class Input extends Component { render() { return React.createElement( "div", null, React.createElement("input", { value: this.state.title, onChange: this.changeHandle.bind(this) }), React.createElement( "button", { onClick: this.clickHandle.bind(this) }, "submit" ) ); } }
这就是通过transform-react-jsx编译jsx语法的过程。
我们说React.createElement是可以改的,然后在demo.jsx上方加一行
/* @jsx h*/
然后运行
babel --plugins transform-react-jsx demo.jsx
就发现createElement被改成了h函数