1. 引入React
- CDN引入(一般不用,了解即可)
<div id="app"></div>
<script src="https://cdn.bootcss.com/react/16.10.2/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.10.2/umd/react-dom.development.js"></script>
<script src="src/index.js"></script>
本地则项目可以用parcel运行
cjs和umd的区别:
cjs全称是CommonJS,时Node.js支持的模块规范
umd是统一的模块定义,兼容各种模块规范(含浏览器)
理论上是优先使用umd,同时支持Node.js和浏览器
最新的模块规范使用import和export关键字
- 通过webpack引入(一般不用)
yarn add react react-dom
import React from 'react' // 变量大写
import ReactDom from 'react-dom'
注意大小写
- 新手用create-react-app,老手自己配webpack/rollup
// 方法一:
yarn global add create-react-app
create-react-app react-demo
// 根据提示符继续操作
// 方法二:打开官网看文档最新使用方法npx
React实现n+1(很麻烦)
失败的案例:
const React = window.React;
const ReactDOM = window.ReactDOM;
const root = document.querySelector("#root");
let n = 0;
const App = React.createElement("div", { className: "red" }, [
n,
React.createElement(
"button",
{
onClick: () => {
n += 1;
}
},
"+1"
)
]);
ReactDOM.render(App, root);
为什么点击按钮数字未发生变化?
因为App=React.create...只执行了一次
如何让他重新执行以获取n的最新值?想想6个6案例
经典面试题之6个6
- 打印6个6
let i;
for(i=0; i<6; i++){
setTimrout(()=>{console.log(i)}, 1000)
}
解释:当 i=0 时,setTimeout说我一会就执行;i=1 时,还说我一会再执行。。。一直到 i=5 时,他还说我一会就执行,i++=6,这时候setTimeout要执行了,每隔一秒打印i,循环了6次
- 打印0-5
- 语法糖:js为了方便小白使用遍历0-5而创造的方法
for(let i=0; i<6; i++){
setTimeout(()=>{console.log(i)}, 1000)
}
当你这样写的时候就相当于如下写法:这样保证了每次循环内部j的值与setTime函数保持同步(不要用var因为他会让作用域跑到最外边)
for(i=0; i<6; i++){
let j=0;
setTimeout(()=>{console.log(j)}, 1000)
}
2. 立即执行函数:将后括号的实参复制给前括号的形参
for(var i; i<6; i++){
!function(j){ // 加!是为了不让函数报错;j为形参可取任意变量
setTimeout(()=>{console.log(i)}, 1000)
}(i)
}
由上得出更新视图的方法:将App变为函数
const React = window.React;
const ReactDOM = window.ReactDOM;
let n = 0;
const App = () =>
React.createElement("div", null, [
n,
React.createElement(
"button",
{
onClick: () => {
n += 1;
console.log(n); //这一句是精髓
ReactDOM.render(App(), document.querySelector("#app"));
}
},
"+1"
)
]);
ReactDOM.render(App(), document.querySelector("#app"));
函数本质:延迟
setTimeout(fn, 0) 含义:在0s后,尽快执行fn
普通代码let b=1+a会立即求出b的值
函数let f=()=>1+a,let b=f会等调用时才求值(延迟求值),且求值时才会读取a的最新值
2. React元素和函数组件
App1 = React.createElement('div', null, n) // 创建div标签,无className/id,内容为n
App1 是一个React元素
App2 = ()=> React.createElement('div', null, n)
App2 是一个React函数组件
即App2是延迟执行的代码,会在被调用时执行(同步异步关注的是得到结果的时机)
React元素:
虚拟DOM对象:createElement的返回值代表一个div,但不是真正的div这个element称为虚拟DOM
()=>React元素:
DOM Diff算法:该元素返回createElement的函数,也代表一个div。这个函数多次执行,每次执行得到最新的虚拟div。React对比两个虚拟div,找出不同来局部更新视图。找不同的算法叫DOM Diff
3. JSX用法
vue-loarder
.vue文件里使用
<template><script><style>,通过vue-loader变成一个构造选项
JSX
webpack内置的babel-loader插件让我们可以使用jsx:将
React.createElement('button',{onClick: add}, '+1')变成<button onClick="add">+1</button>
方法一:CDN(生产环境不要用,效率低,且不支持src)
该方法下载一个babel.min.js,利用它在浏览器端把jsx语法转译成js
<script src="https://cdn.bootcss.com/babel-standalone/7.0.0-beta.3/babel.min.js"></script>
<script type="text/babel">
let n = 0;
const App = () => (
<div>
{n}
<button
onClick={() => {
n += 1;
render();
}}
>
+1
</button>
</div>
);
const render = () =>
ReactDOM.render(<App />, document.querySelector("#app"));
render();
</script>
方法二:webpack+babel-loader(新手跳过)
方法三:使用create-react-app
yarn start后你会发现webpack让js默认走babel-loader,App.js默认使用了jsx语法
JSX注意事项
- 变量,函数,对象,标签里的JS代码用{}包起来;{}会解析成js,()会解析成HTML
- return要加(),否则他返回undefined
- 注意className:
<div className="red">n</div>
eg:条件循环与判断
三目运算符判断
import React from "react";
const App = ()=> {
return (
<div>App组件
<Component />
</div> // React.creatElement()
)
}
const Component = ()=> {
let n = 2;
return n%2 === 0 ? <div>{n}是偶数</div> : <sapn>{n}是奇数</sapn>
}
export default App;
// 第11行可以放在变量里再返回
const Component = ()=> {
let n = 2;
const inner = n%2 === 0 ? <div>{n}是偶数</div> : <sapn>{n}是奇数</sapn>;
const content = (
<div>
{inner}
</div>
)
return content;
}
条件判断式
const Component = ()=> {
let n = 2;
let inner;
if(n%2===0){
return inner = <div>{n}是偶数</div>;
}else{
return inner = <span>{n}是奇数</span>
}
const content = (
<div>
{inner}
</div>
)
return content;
}
eg:循环语句
js内置函数遍历数组
const Component = (props)=> {
return (<div>
{ props.numbers.map((n,index)=>{
return <div>下标{index}值为{n}</div>
})
}
</div>)
}
for循环
import React from "react";
const App = ()=> {
return (
<div>App组件
<Component numbers={[1,2,3]}/>
</div> // React.creatElement()
)
}
const Component = (props)=> {
const array=[];
for(let i=0; i<props.numbers.length; i++){
array.push(
<div>{i}:{props.numbers[i]}</div>
)
}
return <div>{array}</div>
}
export default App;
其实这样写就行: