目录
- react
- 小程序
- vue
- typescript
- 经验(踩坑)
react
useMemo 和 useCallback 都是用来做性能优化的,把 useMemo 当成一个值,把 useCallback 当成一个函数即可。
useEffect
useEffect 是在布局(layout)和绘制(paint)之后触发的。
useEffect 不提供依赖数组和提供空数组有什么区别?
给它一个空数组就像 componentDidMount 一样,它只运行一次。
不给它第二个参数充当 componentDidMount 和 componentDidUpdate ,因为它首先在安装上运行,然后在每次重新渲染时运行。
useEffect 忽略依赖列表的 functions 时, 是否安全?
答案是,否。看个示例:
function Example({ someProp }) {
function doSomething() {
console.log(someProp);
}
useEffect(() = >{
doSomething();
}, []); // 🔴 This is not safe (it calls `doSomething` which uses `someProp`) }
}
可以改进一下,将 function 丢进 useEffect 的回调里:
function Example({ someProp }) {
useEffect(() = >{
function doSomething() {
console.log(someProp);
}
doSomething();
},
[someProp]); // ✅ OK (our effect only uses `someProp`)
}
也可以使用 useCallback 包裹函数:
function Example({ someProp }) {
const doSomething = useCallback(() = >{
console.log(someProp);
},
[someProp]);
useEffect(() = >{
doSomething();
},
[doSomething]);
}
useCallback
使用空数组作为输入的 useCallback 和没有第二个参数的 useCallback 之间有什么区别?
如果第二个参数是一个空数组,则该值将被内存一次并始终返回。
如果省略第二个参数,该值将永远不会被内存。
useLayoutEffect
useEffect 和 useLayoutEffect 的区别:
useEffect 是异步执行的,而useLayoutEffect是同步执行的。
useEffect 的执行时机是浏览器完成渲染之后,而 useLayoutEffect 的执行时机是浏览器把内容真正渲染到界面之前,和 componentDidMount 等价。
一般会影响到渲染的操作尽量放到 useLayoutEffect 中去,避免出现闪烁问题。
参考:https://zhuanlan.zhihu.com/p/348701319
小程序
使用 Component 来实现接收跳转参数,无需通过 onLoad 的 options 参数获取哦:
只需在 Component 里面声明 properties 即可, 别的页面跳转过来待参,就可以通过 this.data 获取到相应的 property。
普通页面:
<navigator url="/pages/组件页面?activeIndex=1">我是跳转按钮</navigator>
组件页面:
Component({
properies: {
activeIndex: String,
},
methods: {
onLoad() {
console.log(this.data.activeIndex); // '1'
}
}
})
小程序页面返回带参方案:
通过 navigateTo 的 success 的 response 里的 eventChannel 来向目标页发布事件,而目标页可通过this.getOpenerEventChannel() 来监听事件,示例:
// 当前页
wx.navigateTo({
url,
success: ({ eventChannel }) = >{
eventChannel.emit('init', {
a: 1
});
}
});
// 目标页
ready() {
this.getOpenerEventChannel().on('init', ({
a
}) = >{
// doSomething
});
}
ios 扫小程序码没有进入小程序,而是进入一个空白网页:
ios 需要有权限才可访问小程序,改 appid,需要已经添加过开发者的 appid
vue
自动引入路由实现方案:(底层是利用 require.context api 实现,即是说,require.context 可以引入多个文件)
路由的目录为:
router
- modules
- index.js
const modules = require.context('./modules', true, /\.js$/);
modules.keys().forEach(name => {
const module = modules(name);
if (module.default) {
addRoute(module.default);
} else {
Object.values(module).forEach(addRoute);
}
});
typescript
TypeScript 中当一个变量为 object 或 null 时,使用解构赋值可能报错的解决方法(在变量后面加个!即可):
type SomeData = {
a: string;
b: string;
c: string;
};
const someData: SomeData | null = null;
const { a, b, c } = someData!;
类型推断
可以合理利用类型推断,节省返回参数声明。
示例:
// api.ts
export function getSomething() {
return get<Res<Something[]>>({
url: xxx
});
}
// index.ts
import { getSomething } from './api';
const _getSomething = async () => {
/**
* 此处的 data 可以不做类型声明,因为在 api.ts 里面已经声明了
* 然后 return 即会触发 typescript 的类型推断,因此推断出 data 的类型了
*/
const { data } = await getSomething(6);
// do something
};
经验(踩坑)
Taro-cropper 在某些情况下“完成”按钮没显示出来:
虽然不知道具体原因,但是翻看其源码可以看到它的 props 里有一行注释:
hideFinishText: boolean, // 隐藏完成按钮(可以自己实现,然后调用本实例的cut方法进行剪裁)
因此,解决方案就是自己实现一份“完成”按钮,Over。
带分页数据的实时刷新方案:
可以以第一页的数据为模板,在轮询的时候进行比较,如果出现差异,则为(数据)有更新,然后更新数据为最新第一页数据即可。
export default 不能正确解构:
export default 经过了 webpack的构建后,会变成类似:
import a from './a'
a.default.b
因此无法通过解构 a 来拿到 b,如果想要能正确解构拿到变量,尽量这样操作:
export const b = 1