react笔记(deprecated)
coderhyh 2/17/2022 笔记
# React
jsx => js和html混合的写法
需要经过编译
方便理解:新增了数据类型 标签片段 <div></div>
遇到 < 解析模板片段
遇到 {} 解析js
# 初识react
语法
<div id="app"></div>
<script type="text/babel">
let x=<h1>hello</h1>;
// 第一个参数 模板结构
// 第二个参数 挂载节点
ReactDOM.render(
<div> hello </div>,
document.getElementById("app")
)
</script>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
插值
<script type="text/babel">
let num=100;
let url="http://www.baidu.com"
// 第一个参数 模板结构
// 第二个参数 挂载节点
ReactDOM.render(
<div>
{/*标签内容插值*/}
hello {num}
{/*标签属性 插值*/}
<a href={url}>百度</a>
</div>,
document.getElementById("app")
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
类名和样式
<h1 className={cn}>hello</h1>
<!-- 外层{}为使用js 对象形式 -->
<h1 style={{fontSize:"50px",color:"blue"}}>行内样式</h1>
1
2
3
2
3
正常jsx并不会解析标签字符串 即: let str="<em>hello</em>"
如想解析字符串标签 则可以使用 dangerouslySetInnerHTML
let str="<em>hello</em>"
ReactDOM.render(
<div>
{/*解析字符串标签*/}
<h1 dangerouslySetInnerHTML={{__html:str}}></h1>
</div>,
document.getElementById("app")
)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
注意:
通常来讲,使用代码直接设置 HTML 存在风险,因为很容易无意中使用户暴露于跨站脚本(XSS) (opens new window)的攻击。
因此,你可以直接在 React 中设置 HTML,但当你想设置 dangerouslySetInnerHTML
时,需要向其传递包含 key 为 __html
的对象,以此来警示你。
# 函数式组件
// 函数式组件 容器组件
// 首字母大写
let List=()=>{
return <h1>列表</h1>
}
ReactDOM.render(
<div>
{List()}
<List/>
<List></List>
</div>,
document.getElementById("app")
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
props
let List=({a,b})=>{
return <h1>{a}---{b}</h1>
}
ReactDOM.render(
<div>
<List a="100" b="500"/>
</div>,
document.getElementById("app")
)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
插槽
props.children
访问组件标签内填写的内容 ---- Vue slot
let Mark=props=>{
return(
<div className="wrap">
<div className="content">{props.children}</div>
</div>
)
}
ReactDOM.render(
<div>
<Mark>abc</Mark>
</div>,
document.getElementById("app")
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 类组件
创建类组件
class Btn extends Component{
constructor(props){
super(props);
// 状态
this.state={
num:100
}
}
render(){//当前组件的模板
let {num}=this.state;
return(
<div>
<button>{num}</button>{/* 使用bind 或 箭头函数都可以 */}
<button onClick={this.increase.bind(this)}>+</button>
<button onClick={()=>{this.increase()}}>+</button>
<button onClick={()=>{this.setNum(500)}}>500</button>
</div>
)
}
// 书写方法
increase(){
this.setState({
num:this.state.num+1
})
}
setNum(a){
this.setState({
num:a
})
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
生命周期
// 挂载完毕 第一次插入真实DOM
componentDidMount() {
console.log("挂载完毕", app.innerHTML);
}
// 卸载
componentWillUnmount(){ }
// 组件更新
componentDidUpdate(oldProps,oldState){
console.log(oldState.list,this.state.list)
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Hook
函数式组件 --- 无状态组件
类组件 --- 具有状态
Hook
在函数组件中使用 可以让函数组件拥有状态
// useState创建响应状态的hook
// useEffect 处理生命周期相应任务
let {useState,useEffect}=React;
let App=()=>{
// 响应数据及修改方法
let [num,setNum]=useState(10)
// componentDidMount 只在初始时运行一次 可以在这里请求数据
useEffect(()=>{
console.log("创建组件")
},[])
// DidMount+Didupdate 初始+任意数据变化
useEffect(()=>{
console.log("初始+更新")
})
// DidMount+某个数据的更新 !!!!!
useEffect(()=>{
console.log("初始+num变化")
},[num])
// 卸载
useEffect(()=>{
return ()=>{//卸载时运行
console.log("卸载")
}
},[])
// 模板
return(
<div>
<h1>{num}</h1>
<button onClick={()=>setNum(num+1)}>按钮</button>
</div>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
useEffect
生命周期是可以写多个的;比如一个作为初始请求;一个作为监听等
# 访问DOM
let {useRef}=React;
let App=()=>{
// 创建ref ---1
let btn=useRef(null);
// 第一次挂载时 mounted
useEffect(()=>{
// 通过current属性访问DOM节点 ---3
console.log(btn.current.offsetHeight);
},[])
return (
<div>
{/*绑定元素 ---2*/}
<button ref={btn}>按钮</button>
</div>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 组件通信
子到父
let Child=({data,del})=>{
return (
<ul>
{
data.map((item,index)=>{
{/* 子组件接收 调用 */}
return <li onClick={()=>del(index)} key={item}>{item}</li>
})
}
</ul>
)
}
let Parent=()=>{
let [arr,setArr]=useState(["苹果","西瓜","香蕉"])
//把函数传给子组件
let del=index=>{
let data2=JSON.parse(JSON.stringify(arr));
data2.splice(index,1);
setArr(data2);
}
return (
<div>
{/*谁的数据谁修改 把父组件修改数据的方法 通过props传入子组件*/}
<Child data={arr} del={del}/>
</div>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
注意:
如果是类组件的话 在传给子组件的时候 需要改变this指向
<Child data={arr} del={del.bind(this)}/>
# CLI
安装
npm i create-react-app -g
create-react-app project
# 私有化css
正常 react
的css都是公用的
想要css私有化 需要使用 module
// 首先创建 fileName.module.css
.title {color: pink}
1
2
2
// css module 私有化css样式
import style from "fileName.module.css";
//使用
<h1 className={style.title}>首页</h1>
1
2
3
4
2
3
4