#React js 基础
React 基础
- React 简介
- JSX 模板语法
- props & state
- 生命周期
- 事件处理
- 条件渲染
- 列表
- create-react-app
- immutable 及immer
什么是react
- 声明式编程
- 命令式编程 侧重过程
// 第一步
const map = new Map.map(document.getElementById('map'),{
zoom:4,
center:{lat,lng},
})
// 第二步 创建标记
const marker = new Map.marker({
position:{lat,lng},
title:'Hello Marker',
})
// 第三步 地图上添加标记
marker.setMap(map);
// 声明式编程
<Map zoon={4} center={(lat,lng)}>
<Marker position={(lat,lng)} title={"Hello Marker"}>
</Map>
- 高效 对dom模拟
- 灵活
怎么学
尝试使用你熟悉的领域 来去解释你正在熟悉的领域
框架 永远是“器” ,解决问题的办法是“术”,学习体系“道”,以道驭术。
与Vue对比
- 相同点
- 虚拟dom
- 基于组件的开发模式
- 专注于视图
- 不同点
- vue mvvm
- react ui = render(data)
props 只读的属性 父子流动
state setState
- 运行时 vs 编译时
- vue
- 编译时: template + jsx 受限制语法v-if v-for template vue3按需编译 静态标记
- 运行时 diff比较
- react
- 编译时:jsx -> 编译成js -> createElement
- 侧重运行时
- vue
- 数据是否可变
- react immutable 不可变
this.state.xxx = xxx -> this.setState - vue mutable 响应式
- react immutable 不可变
- 语法不同
react jsx
vue SFC 组件进行拆分成三块 template js css
jsx 模板语法
UI 逻辑
const name = "Josh Perez";
const element = <div>Hello,{name}</div>
function formatName(user){
return user.firstName +' '+user.lastName
}
const element = <h1>Hello,{formatName(user)}</h1>
function getGreeting(user){
if(user){
return <h1>Hello,{formatName(user)}</h1>
}
return <h1>Hello, Stranger.</h1>
}
-
jsx 是 React.createElement 的语法糖 (jsx 通过babel 转化成React.createElement)
React.createElement- type
- props
- children
=> vdom 两次虚拟dom进行diff比较 ReactDom.render(VDOM,“root”) => 遍历虚拟DOM转成真实节点,进而挂载到节点上
-
vue jsx 使用h函数
组件
// 函数式组件 函数首字母大写
function Welcome(props){
return <h1>Hello, {props.name}</h1>
}
const element = <Welcome name="Sara"/>
ReactDOM.render(element,document.getElementById("root"))
// class 组件
class Welcome extends React.Component{
render(){
return <h1>Hello,{this.state.name}</h1>
}
}
受控组件 和 非受控组件
- 受控组件 控制表单校验等等
- 非受控组件 input自身维护的状态,外界无法获取数据
state 和 props
- state 组件内
- v18前
- 在组件生命周期 或者React 合成事件 setState 都是异步的
- setTimeout 或者原生dom 事件setState 同步的
- v18后
都是异步的 批处理 (多次调用被合并)
想让当前操作是同步操作 利用flushSync 取消批处理
updateCount(){
flushSync(()=>{ //
this.setState({
message:'Alex'
})
});
console.log("updateCount",this.state.message)
this.setState((state)=>({ // 多次调用拿到上次修改的结果 ,不被合并
count:state.count + 1,
}))
this.setState((state)=>({
count:state.count + 1,
}))
this.setState((state)=>({
count:state.count + 1,
}))
}
props 外部传入
生命周期 class组件
挂载 -> 更新 -> 卸载
函数式组件主要式监听变量进行修改
事件处理
合成事件 (react对事件的包装 )
- 进行浏览器兼容 跨平台 事件代理
- 避免垃圾回收 React事件池
- 方便事件统一管理
与原生事件有哪些区别 - 命名不一样 React: 小驼峰 onClick
- 事件处理函数写法不一样
- 阻止默认行为方式不同
event.preventDefault()
if else 渲染
与 或 非 运算符
如何阻止组件渲染
function Name(props){
if(!props){
return null
}
return <div>Hello</div>
}
列表遍历
function NumberList(props){
const numbers = props.numbers
const listItems = numbers.map((number)=>(
<li key={number.toString()}>{number}</li>
))
return <ul>{listItems}</ul>
}
const numbers = [1,2,3,4,5];
ReactDOM.render(
<NumberList numbers={numbers}/>,
document.getElementById("root")
)
// 若没有key,回warning a key should be provided for list items
// key可以帮助react diff,最好不要用index作为key,回导致性能变差;
// 如果不指定显示的key值,默认使用索引用作列表项目的key值;
refs
允许访问当前dom节点
React.createRef();
当前dom节点 current对象上
create-react-app 脚手架
immutable 及immer 更简洁,性能更优
官方地址:https://immutable-js.com/
js 对象 mutable
var foo = {a:1};
var bar = foo;
bar.a = 3;
// foo{a:3}; 引用对象指向同一个内存对象
a = deepCopy(b);
a === b // false;
目的:得到对象,不影响之前的对象,得到更加高效的修改
updateCount(){
this.setState(
produce((draft) => {
draft.members[0].age++;
})
)
}