1.Sass的镜像配置
yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g
2. useState(状态)
//useState返回个数组,第一个参数是state的值,第二个参数是改变state值的函数
//useState本身就是一个函数,函数接收值是state的初始值
function Example() {
const [show, setShow] = useState(true);
const [count, setCount] = useState(0);
return (
<div>
{show && <h3>标题的显示和隐藏</h3>}
<Button onClick={(e) => setShow(!show)}>显示/隐藏</Button>
<Count name="张三" count={count} changeCount={changeCount}></Count>
</div>
);
}
function Counter(props) {
const { count, name, changeCount } = props;
return (
<div>
<h3>
{name}开始计数:{count}
</h3>
<Button onClick={(e) => changeCount()}>计数</Button>
</div>
);
}
3.useEffect (副作用)
import React, { useEffect, useState } from "react";
function Test() {
const [count, setCount] = useState(0);
// 第一个参数是个函数,表示是副作用要执行的操作
useEffect(() => {
console.log("组件的mount和更新");
});
// 第二个参数是执行第一个参数函数的依赖,当依赖变化时会进行更新执行
// 下面数组是空,所以只有加载的第一次才会执行,后面就不会执行了
// 类似 componentDidMount
useEffect(() => {
console.log("组件的mount");
}, []);
// 当有依赖时,依赖更新就会执行函数,包括返回的函数
// 而且useEffect是可以多个同时使用的,顺序从上到下
useEffect(() => {
console.log("组件的mount和更新2");
return () => {
console.log("返回的函数");
};
}, [count]);
// 第一个参数函数,返回值如果是一个函数,表示的是componentWillUnmount,组件卸载
// 组件卸载的操作可以在返回的函数里面进行操作
// 此时没有依赖,只会执行一次,就是组件第一次加载
useEffect(() => {
console.log("组件的mount");
return () => {
console.log("componentWillUnmount 组件卸载");
};
}, []);
return (
<>
<p>{count}</p>
<button onClick={(e) => setCount(count + 1)}>改变count的值</button>
</>
);
}
export default Test;
4.useRef(获取ref实例)
// ref的使用
function RefDom() {
const ref = useRef(); //创建ref
const valRef = useRef(0); // 记录值(上一次的值)
const [count, setCount] = useState(0);
useEffect(() => {
ref.current.value = "ref的测试"; //操作dom
}, []);
// useEffect是在render结束后进行执行
useEffect(() => {
valRef.current = count; //此时只是更新了valRef.current的数值,组件不会触发render
}, [count]);
return (
<div>
{/*ref记录值的使用*/}
<p>ref的记录上次的值:{valRef.current}</p>
<p>最新的值: {count}</p>
<Button type="primary" onClick={(e) => setCount(count + 1)}>
计数
</Button>
<br /> <br />
{/*赋值ref到dom*/}
<input ref={ref} />
</div>
);
}
5.useCallback,memo, useMemo的使用
memo
就是类似PureComponent,只不过memo针对的是函数式组件,进行浅比较,对性能进行优化
useMemo
一般是对高计算的操作进行优化,返回一个记忆的值, 仅会在某个依赖项改变时才重新计算记忆的值
useCallback
和useMemo差不多,只不过返回一个记忆的回调函数,是useMemo的特殊版
// 此组件除了接收属性,还接收了函数
// 如果父组件因为除了count其他的元素进行重新render,重新定义了changeCount函数,那么就不能起到性能优化的作用了
// memo就毫无意义了,所以要对changeCount进行记忆,只有count改变时候在进行重新定义
const Count = memo((props) => {
console.log("counter的渲染");
const { count, name, changeCount } = props;
return (
<div>
<h3>
{name}开始计数:{count}
</h3>
<Button onClick={(e) => changeCount()}>计数</Button>
</div>
);
});
function Example() {
console.log("父元素的渲染");
const [show, setShow] = useState(true);
const [count, setCount] = useState(0);
// 对changeCount进行记忆,只有count变化,才对函数进行执行
// show的变化不会引起函数的执行,也不会改变changeCount,导致Count组件的memo不生效
const changeCount = useCallback(() => {
console.log("父计数渲染");
setCount(count + 1);
}, [count]);
// 对复杂的运算进行记忆,不用频繁执行,返回个值
// 这里只是举个例子
const total = useMemo(() => {
console.log("计算");
let t = 0;
for (let i = 0; i <= count; i++) {
t += i;
}
return t;
}, [count]);
return (
<div>
{show && <h3>标题的显示和隐藏</h3>}
<Button onClick={(e) => setShow(!show)}>显示/隐藏</Button>
<hr />
<h3>总数的和:{total}</h3>
<Count name="张三" count={count} changeCount={changeCount}></Count>
</div>
);
}
6. 自定义hook(有点mixin的意思,通过hook对组件进行混入)
函数名字要以use开头,这是约定,这样才能使用基础hook,比如useState之类的
import { useEffect, useState, useCallback } from "react";
//这是一个记录滚动位置的自定义hook
export const useScroll = () => {
const [pos, setPos] = useState(0);
// 记忆记录位置的操作,第一次加载的时候定义下
const getScrollPos = useCallback(() => {
setPos(window.scrollY); //改变位置,触发render
},[]);
// getScrollPos改变时候,才会重新定义事件
// getScrollPos被记忆了,所以不会改变,事件就只会被定义一次
useEffect(() => {
document.addEventListener("scroll", getScrollPos);
return () => {
document.removeEventListener("scroll", getScrollPos);
};
}, [getScrollPos]);
return pos; //如果只有一个值,可以直接返回,如果多个可以用[]的方式
};
// 使用方式
import { useScroll } from "./hk";
function DefineHook() {
const pos = useScroll();
return <h4>当前的滚动位置是:{pos} px</h4>;
}