React的诞生-Day1
2018-09-06 本文已影响0人
妖妖劲
设计的想法
原生的js
在我们操作HTML中的DOM的过程中,我们一般是有三步:
- 从页面中获取DOM,
- 在JS中进行操作,
- 把修改好的DOM返回到页面中。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<span id = 'result'>0</span>
<button id='add'>+</button>
<script>
let result = document.querySelector('#result')
let add = document.querySelector('#add')
add.addEventListener('click',function(){
let num = parseInt(result.innerText,10)
num += 1
result.innerText = num
})
</script>
</body>
</html>
像我们这个就是,先从页面中获取span里的内容,点击按钮的话会用js操作这个内容,然后把内容更新到页面中。
使用react
原生js中有3步,react程序员的想法是,把第一步干掉,就是从页面获取内容干掉。
干掉的原理:
- 首先一个空页面,react里面直接生成一个DOM(虚拟DOM),然后同步到页面(元素)中。
- 如果页面需要更新,重新生成一个DOM,然后再更新到页面中。
- 永远不从页面里取东西,只从页面里放东西。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.production.min.js">
// 使用react要引入两个js文件
</script>
<title>JS Bin</title>
</head>
<body>
<div id='root'></div>
<button id="add">+</button>
<script>
let num = 0
let span =React.createElement('span',{},num)
ReactDOM.render(span,document.querySelector('#root'))
let add = document.querySelector('#add')
add.onclick =()=>{
num +=1
let span =React.createElement('span',{},num)
ReactDOM.render(span,document.querySelector('#root'))
}
</script>
</body>
</html>
react一直在做的就是两件事:
- 生成虚拟dom
- 同步到页面中
局部更新
react 在第二次更新同一个元素的时候,会和上一次相对比,只更新有变化的,这就叫局部更新
代码优化1
把一直重复做的两件事变成一个函数,然后一直调用就行了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id='root'></div>
<button id="add">+</button>
<script>
let num = 0
render()
let add = document.querySelector('#add')
add.onclick =()=>{
num +=1
render()
}
function render(){ //把重复的操作变成一个函数
let span =React.createElement('span',{},num)
ReactDOM.render(span,document.querySelector('#root'))
}
</script>
</body>
</html>
代码优化2
把所有的操作放进函数里
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id='root'></div>
<script>
let num = 0
let onClickButton =()=>{
num += 1
render()
}
render()
function render(){
let span =React.createElement('span',{},num)
let button = React.createElement('button',{onClick:onClickButton},'+')
let div = React.createElement('div',{},span,button)
ReactDOM.render(div,document.querySelector('#root'))
}
</script>
</body>
</html>
上面的render函数干的事:
- 创建span标签,内容为num
- 创建button标签,监听点击事件和内容
- 添加div标签,把上面两个创建的标签放进里面作为子标签。
- 把div标签放进页面中id为root的元素中
优化代码3
把相同的语法声明成一个变量h(一般是这个)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id='root'></div>
<script>
let num = 0
let onClickButton =()=>{
num += 1
render()
}
render()
function render(){
let h = React.createElement //这个变量名一般都叫h
let span = h('span',{},num)
let button = h('button',{onClick:onClickButton},'+')
let div = h('div',{},span,button)
ReactDOM.render(div,document.querySelector('#root'))
}
</script>
</body>
</html>
代码优化4
不声明较少用的变量,直接使用语句
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id='root'></div>
<script>
let num = 0
let h = React.createElement
let onClickButton =()=>{
num += 1
render()
}
render()
function render(){
let div =
h('div',
{},
h('span',{},num) , //变量声明就用一次,太浪费
h('button',{onClick:onClickButton},'+')) ReactDOM.render(div,document.querySelector('#root')
)
}
</script>
</body>
</html>
JSX
写react的程序员发现这两段代码惊人的相似
h('div',
{class:'parent'},
h('span',{className:'red'},num) ,
h('button',{onClick:onClickButton},'+'))
ReactDOM.render(div,document.querySelector('#root')
)
<div class='parent'> //正括号就是开始标签
<span class='red'>num</span>
<button onClick=onClickButton>+</button>
</div> //反括号就是结束标签
所以这位程序员就想,能不能让开发者写下面这样的代码,然后使用一个程序翻译成上面那样的代码,然后它们就做出来了,那个程序叫JSX翻译器,下面的语法叫JSX(一定要注意,那不是在写html,是用html的形式写js)
注意:所有是变量或函数的东西,要加个花括号。
JSX语法
<div class='parent'> //这个class可以写成className,如果不报错可以直接写成class
<span className='red'>{num}</span> //要的是变量num,不是字符串num
<button onClick={onClickButton}>+</button>
</div>
在这个网站可以进行转换:https://www.babeljs.cn/docs/setup
使用JSX语法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id='root'></div>
<script>
let num = 0
let onClickButton =()=>{
num += 1
render()
}
render()
function render(){
let div =
<div className='parent'>
<span className='red'>{number}</span>
<button onClick={onClickButton}>+</button>
</div>
RestDOM.render(div,document.querySelector('#root'))
</script>
</body>
</html>
但是直接这样写是不能运行的,要使用的话可以使用下面的方法。
- webpack
- 在js bin上面的js页面上选择JSX