首先 useEffect
接收两个参数,回调函数(callback)和依赖的数组(desAry)
function myUseEffect(callback, depsAry) {
}
需要判断下 callback
是否是函数,如果不是函数就报错
function myUseEffect(callback, depsAry) {
if (Object.prototype.toString.call(callback) !== '[object Function]') {
throw new Error('myUseEffect 函数的第一个参数必须是函数')
}
}
接着需要判断 depsAry 是否传递,如果没有传递直接调用回调函数就可以了
if (typeof depsAry === 'undeifined') {
callback();
}
还需要判断 depsAry 是否是一个数组,如果不是就报错
if (typeof depsAry === 'undeifined') {
callback();
} else {
if (Object.prototype.toString.call(depsAry) !== '[object Array]') {
throw new Error('myUseEffect 函数的第二个参数必须是数组')
}
}
如果是数组,需要拿当前的依赖值和上一次的依赖值作对比,如果有变化就执行 callback
let preDepsAry = [];
if (typeof depsAry === 'undeifined') {
callback();
} else {
if (Object.prototype.toString.call(depsAry) !== '[object Array]') {
throw new Error('myUseEffect 函数的第二个参数必须是数组')
} else {
const hasChanged = depsAry.every((dep, index) => dep === preDepsAry[index]) === false;
if (hasChanged) {
callback();
}
preDepsAry = depsAry;
}
}
但是 useEffect
是可以有多个的,所以 preDepsAry
需要是一个二维数组
这时候就需要索引来标识
let effectIndex = 0;
对比的时候
if (Object.prototype.toString.call(depsAry) !== '[object Array]') {
throw new Error('myUseEffect 函数的第二个参数必须是数组')
} else {
const prevDeps = preDepsAry[effectInjdex];
const hasChanged = depsAry. ? depsAry.every((dep, index) => dep === prevDeps[index]) : false;
if (hasChanged) {
callback();
}
preDepsAry[effectIndex] = depsAry;
effectIndex++:
}
再重新渲染的时候,effectIndex
需要恢复成 0
function render() {
stateIndex = 0;
effectIndex = 0;
ReactDom.render(<App />, document.getElementById('root'));
}
完整的代码:
// 渲染函数
function render() {
stateIndex = 0;
effectIndex = 0;
ReactDOM.render(<App />, document.getElementById('root'));
}
const preDepsAry = [];
let effectIndex = 0;
function useMyEffect(callback, depsAry) {
// 判断 callback 是否为函数
if (Object.prototype.toString.call(depsAry) !== '[object Function]') {
throw new Error('myUseEffect 的第二个参数必须是函数')
}
// 判断 depsAry 有没有传递
if (typeof depsAry === 'undefined') {
callback();
} else {
// 判断 depsAry 是否是数组
if (Object.prototype.toString.call(depsAry) !== '[object Array]') {
throw new Error('myUseEffect 的第二个参数必须是数组')
} else {
// 获取上一次依赖
const prevDeps = preDepsAry[effectIndex];
const hasChanged = prevDeps && depsAry.every((dep, index) => dep === prevDeps[index]);
if (hasChanged) {
callback();
}
preDepsAry[effectIndex] = depsAry;
effectIndex++;
}
}
}
网友评论