mvc三层架构
M层数据,V层视图,C层逻辑
react 新特性
jsx语法
JSX语法基础
<div className="className" id={ID}>
<span style={{color:'red',fontSize:'55px'}}>{name}</span>
</div>
const name = 'Hello Word'
<span style={{color:'red',fontSize:'55px'}}>{name}</span>
表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
下面这些都是表达式:
(1). a
(2). a+b
(3). demo(1)
(4). arr.map()
(5). function test () {}
语句(代码):
(1).if(){} (1).if(){}
(2).for(){} (2).for(){}
(3).switch(){case:xxxx}
const data = ['Vue', 'React', 'Animation']
// 只能渲染数组
const VDOM = (
<div>
<h1>HEllo REACT</h1>
<h2>React遍历对象与数组</h2>
<ul>
{
data.map((v, index) => {
return <li key={index}>{v}</li>
})
}
</ul>
</div>
)
ReactDOM.render(VDOM, document.querySelector('#test'))
JSX语法中有三个不一样的属性
1.3. React面向组件编程
1.3.1 函数组件与类组件
- 函数组件
注意点
- 函数式组件定义时首字母必须
大写
render
渲染时必须使用标签
- 函数式组件定义时首字母必须
function MyComponent(){
console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
}
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
- 类组件
注意点
- 类组件必须继承React.Component
- 必须写render函数
- 必须有返回值
class MyComponent extends React.Component {
render(){
//render是放在哪里的?—— MyComponent的原型对象上,供实例使用。
//this指向?—— MyComponent的实例对象 <=>MyComponent组件实例对象。
console.log('render中的this:',this);
return <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>
}
}
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
组件实例的三大特性
state数据存储状态
注意点 React默认开启严格模式
普通函数的形式直接在事件中调用 this的指向undefined 可以在构造函数中利用bind,apply,call 改变this的指向
setState 用于更新state中的数据,里面包含一个对象要改变的值 (注意点,setState是异步的,可以传递对象或者函数,且每次调用 render函数都会重新渲染)
// state使用
class Wether extends React.Component {
// 1. 继承React组件实例上添加的属性
// 2. 构造器的this指向构造函数的实例对象
// 3. render() 函数中的this也指向构造函数的实例对象
constructor(props) {
// super继承父组件属性
super(props)
this.state = { isHost: false, wind: '炎热' }
// 改变this的指向
this.demo = this.demo.bind(this)
}
render() {
const { isHost } = this.state
// this.function 是直接调用this指向window
return (
<div onClick={this.demo} >{isHost ? '雨天' : '晴天'}</div>
)
}
demo() {
// this.state.isHost = !this.state.isHost // 取反 状态不能直接更改(React响应捕捉不到)
let isHost = this.state.isHost
// 修改状态需要用setState
this.setState({ isHost: !isHost })
}
}
ReactDOM.render(<Wether />, document.querySelector('#test'))
简写的方式
class Wether extends React.Component {
// constructor(props) {
// super(props)
// // 改变this指向
// this.speck = this.speck.bind(this)
// }
// 简写: 直接原型上追加属性
state = {
name: '张三',
isName: true
}
render() {
let { isName, name } = this.state
return (
<div onClick={this.speck} style={{ fontSize: '24px', color: 'red' }}> {isName ? '显示名字' : `不显示${name}`}</div>
)
}
// 直接追加到原型上这里的this就是指原型
speck = () => {
let isName = this.state.isName
// setState里面必须包含一个对象
this.setState({ isName: !isName })
}
}
ReactDOM.render(<Wether />, document.querySelector('#test'))
react状态定义
useState使用方法
import React, { useState } from "react";
export default function StateCom() {
const [msg, setMsg] = useState("你好,世界");//注意useState必须在最上面
const handleClick = () => {
setMsg("你好,李焕英");
};
return (
<div>
<h1>{msg}</h1>
<button onClick={handleClick}>按钮</button>
</div>
);
}
react hooks(钩子)
1、useEffect使用方法
Effect Hook 可以让你在函数组件中执行副作用操作
import React, { useEffect, useState } from "react";
export default function UseEffect() {
const [msg, setMsg] = useState("你好,世界");
useEffect(() => {
const timer = setInterval(() => console.log("定时器执行"), 1000);
console.log("使用useEffect模拟componentDidMount生命周期");
return () => {
clearInterval(timer);
console.log("使用useEffect模拟componentWillUnmount生命周期");
};
});
useEffect(() => {
console.log("使用useEffect模拟componentDidUpdate生命周期");
}, [msg]);//这里的第二个参数是监听一个数据的,一旦这个数据发生了变化,就会监听到
return (
<div>
<h1>{msg}</h1>
<button onClick={setMsg("你好")}></button>
</div>
);
}
2、useRef使用方法
1.useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。
2.返回的 ref 对象在组件的整个生命周期内保持不变。
3.本质上,useRef 就像是可以在其 .current 属性中保存一个可变值的“盒子”
import { useEffect } from "react";
import { useRef } from "react";
export default function UseRef1() {
const inputEl = useRef(null); //一般传入null
console.log(inputEl);
useEffect(() => {
console.dir(inputEl.current);
inputEl.current.focus();
}, []);
return (
<div>
<h1 ref={inputEl}>小盒子</h1>
</div>
);
}
3、memo、useMemo、useCallback
memo、useMemo、useCallBack主要用于避免React Hooks中的重复渲染,作为性
能优化的一种手段,三者需要组合并结合场景使用
memo、useMemo、useCallback使用方法
import React, { useCallback, useMemo, useState } from "react";
import B from "./B2";//这里有第二个组件
import C from "./C";//这是第三个组件
export default function A() {
const [count, setCount] = useState(0);
// const handleClick = () => setCount((pre) => pre + 1);
// const aaa = useMemo(() => {
// return handleClick;
// }, []);
// const aaa = useMemo(() => () => setCount((pre) => pre + 1), []); //简写方法
const aaa = useCallback(() => setCount((pre) => pre + 1), []);
console.log("A组件更新啦");
return (
<div>
我被点击了{count}次
<B fn={aaa} />
<C />
</div>
);
}
4、自定义hooks
特点:名字一定是以 use 开头的函数,这样 React 才能够知道这个函数是一个 Hook。
函数内部一定调用了其它的 Hooks,可以是内置的 Hooks,也可以是其它自定义 Hooks。这样才
能够让组件刷新,或者去产生副作用。这里的hooks就是监听浏览器宽度变化的自定义hooks
// 监听浏览器宽度的变化使用到了自定义hooks的特点
// 1是个函数
// 2使用到其他的hooks
import { useEffect, useState } from "react";
// 如果外不需要用到函数内的数据,需要返回指定数据
export const useResize = () => {
let [width, setwidth] = useState(document.body.clientWidth - 30);
// 需要监听width值得变化,做出相应的处理
// eslint-disable-next-line react-hooks/exhaustive-deps
const resizeFn = () => {
setwidth(document.body.clientWidth - 30);
console.log(width);
};
useEffect(() => {
//页面挂载后监听浏览器的宽度变化
window.addEventListener(
"resize",
// console.log("123", width);
// 在窗口大小变化时执行的操作
resizeFn
);
return () => {
window.removeEventListener("resize", resizeFn);
};
}, [resizeFn, width]);
return [width, setwidth];
};
ahooks
ahooks是由蚂蚁 umi 团队、淘系 ice 团队以及阿里体育团队共同建设的 React Hooks 工具ahooks
基于 React Hooks 的逻辑封装能力,提供了大量常见好用的 Hooks,可以极大降低代码复杂度,提升开发效率
使用方法
import React, { useEffect, useState } from 'react'
import axios from 'axios'
import { useRequest } from 'ahooks'
export default function UseRequest() {
const [msg, setMsg] = useState('')
const { data, error, loading } = useRequest(() => {
return axios.get('https://api.uomg.com/api/rand.qinghua', {
format: 'json'
})
}, {
pollingInterval: 10000,
})
console.log(data?.data?.content);
console.log(loading);
return (
<div>{loading ? '正在拼了命的加载....' : data?.data?.content}</div>
)
}
总结
在本篇博客中,深入探讨了 react的使用方法,通过详细的介绍和实际示例,希望读者能够更好地理解如何利用这些 Hooks 构建出强大而优雅的 React 组件。同时,强调了最佳实践,并提供了一些建议,帮助更好地在实际项目中应用这些强大的自定义 Hooks。希望在你的下一个 React 项目中,能够充分发挥 ahooks 的优势,打造出更加精妙的用户界面。