1.最简单的开始:
参考页面:https://raw.githubusercontent.com/reactjs/reactjs.org/master/static/html/single-file-example.html
只需要添加三个相关的react库文件,就可以直接使用react了。
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
其中,babel.min.js是代码转换器,可以在线将ES6的js语言转化为ES5的,方便在不同浏览器上的兼容,直接在线使用的话,对页面的性能影响很不好,不过,单纯练习,认识了解react的api使用,就无所谓了。在工作中的话,是不允许这样子的。这里只是单纯用于了解相关的函数API。
案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
</script>
</body>
</html>
一个简单的hello world出来了。
2.ReactDOM.render:
可以清楚的看到,在这个简单的demo中,使用了<script type="text/babel"></script>,在其中调用了ReactDOM.render函数,这个函数,简单的看一下源码,接收三个参数,element, container, callback。根据上面的效果可以简单的判断出来,element就是被添加DOM元素(虽然它的书写方式很不js),container就是接受之前的节点的父DOM节点,而callback,貌似是一个函数,做一个简单的试验吧。
将代码成如下:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root'),
() => {
console.log('hello world');
document.getElementById('root').innerHTML += "加我一个";
}
);
结果如下:
所以说,简单的试验判断一下,最后的callback参数,就是传入一个回调函数,然后在渲染好元素之后(原来的内容,会自动消失,可以自己尝试),执行这个函数?
(大概吧,更加具体细致的方面,需要全盘解析源代码,目前我也没时间,但是我也是刚开始学的一个菜鸟,emmm)
3.jsx:
ReactDOM.render,光是简单地根据上面地效果,用标准的js执行的话,类似于,先是执行一个原生appendChild,再根据是否有回调函数的参数执行回调函数。(如果传入字符串之类,不对劲地参数,大概是会报错的吧)。
当然,可以明显地看出,ReactDOM.render地第一个参数,是很奇怪的html代码,这就是jsx语言,将html代码与js代码混合在一起。这是由于得到了babel的支持才能实现的,尝试一下,将代码改成如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<!-- <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> -->
</head>
<body>
<div id="root"></div>
<script type="text/javascript">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root'),
() => {
console.log('hello world');
document.getElementById('root').innerHTML += "加我一个";
}
);
</script>
<!-- <script type="text/babel"></script> -->
</body>
</html>
结果如下:
代码会识别不出这是什么东西。(如果是传入一个dom元素的话,也是不行。好像是必须在bebal的前提下,使用jsx,不过没看过具体源码,内部过程不是很了解。)
在jsx中,可以直接使用html代码,它能将对应的html代码视,转化为一个对象,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const hello = <h1>Hello, world!</h1>;
console.log(hello);
</script>
</body>
</html>
结果如下:
也就是,每个jsx代码都会进行babel的转化,变成这样的对象,之后再作为参数传入函数中。其中,可以很明显地看到:typeof是一个Symbol类型的数据,type属性代表节点类型,props中的children代表接节点内容。
(可以在babel标签中,可以看作只有js代码,jsx,视作一个特定的js对象即可)
在jsx代码中,可以使用js代码,在一个大括号中,书写JavaScript 表达式即可(如果要使用大括号作为字符串的话,貌似只能加入到变量中才行......我毕竟只是一只菜鸟,也不知道有没有什么转义的方法)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
var name = "jsx",
hello = <h1>hello, i am {name}</h1>;
console.log(hello);
</script>
</body>
</html>
结果:
props属性下的children数组多了一个元素,就是name变量代表的字符串。(如果不是字符串的话,会toString转化成字符串或者更具内部的机制,转化成别的类型,然后将一个变量作为一个元素,压入数组中)。
如果内部jsx代码中,想给html写子节点的话的话,会在props属性下的children数组中,压入一个新的对象。(这是babel处理jax的机制,一个根节点代表一个最初的对象,所以,不能同时有两个最高的节点,这样的话,会报错。这里可以自己试验一下)
4.React.createElement:
一个简单的使用案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
var hello = React.createElement('h1', {
'data-name': 'hello',
}, 'hello')
console.log(hello);
ReactDOM.render(
hello,
document.getElementById('root')
);
</script>
</body>
</html>
这个函数传入三个参数,type, props, children,type代表转入的节点类型,props代表节点的属性,children代表节点内包含的内容。
有趣的是,这个函数返回的数据,和jsx一样,是一个格式一样的对象。
5.小结:
- 练习的话,可以使用在线直接导入js文件方法,快速的构筑react环境。
- ReactDOM.render,接受三个参数,按顺序分别是,节点元素参数element,父节点DOM元素container, 一个回调函数callback。
- React.createElement,接受三个参数,代表节点类型的字符串type, 代表节点属性的对象props,代表节点内容 children。
- jsx、React.createElement,返回的都是一个对象,包含了dom的相关信息,也是ReactDOM.render接受的第一个元素参数。