面试题
react的useEffect监听对象存在的问题
无法监听对象或数组内的成员改变
import { useEffect, useState } from 'react'
function App() {
const [person, setPerson] = useState({uname: '张三'})
const setUname = ()=>{
person.uname = '李四'+new Date().getTime();
setPerson(person);
console.log(person);
}
useEffect(()=>{
console.log('person发生改变');
},[person])
return (
<>
<button onClick={setUname}>测试</button>
<div>{person.uname}</div>
</>
)
}
export default App
可以看到 即便是对象的属性已经真的改变了,但是useEffect的监听仍然未执行,即没有被监听到。
当然数组也一样。
解决办法: 设置的时候新创建一个对象即可 setXXX([...xxx])
或者setXXX({...xxx})
你平时用fetch多还是axios多 谈谈你做了哪些事情
略
接口被重复调用,响应时长不同,结果被覆盖的问题
频繁调用接口,前面接口返回的数据把后面的覆盖了?
后端node服务器模拟
import url from 'url';
import http from 'http';
const sleep = (timer)=>{
return new Promise((resolve)=>{
setTimeout(()=>{
resolve()
},timer)
})
}
const users = [
{name:'用户1',age:20, desc:'我就是我'},
{name:'用户2',age:18}
];
http.createServer(async (request, respones)=>{
const parseUrl = url.parse(request.url,true);
const uname = parseUrl.query.name;
if(uname === '用户1'){
await sleep(3000)
}
respones.writeHead(200,{'Content-type':'application/json'})
respones.end(JSON.stringify(users.find(it=>it.name===uname)))
}).listen('8080')
axios代码如下
import { useState } from 'react'
import axios from 'axios'
function App() {
const [info, setInfo] = useState({})
const syncInfo = async (name) => {
const { data: infoRes } = await axios.get('http://localhost:8082/info', {
params: { name }
});
setInfo({ ...infoRes })
console.log(infoRes);
}
return (
<>
<button onClick={() => { syncInfo('用户1') }}>测试1</button>
<button onClick={() => { syncInfo('用户2') }}>测试2</button>
<div>{JSON.stringify(info)}</div>
</>
)
}
export default App
取消重复请求,只保留最后一次请求
import { useState } from 'react'
import axios from 'axios'
let cancel;
function App() {
const [info, setInfo] = useState({})
const syncInfo = async (name) => {
if(cancel){ cancel();} // 请求之前判断 有没有存在的请求 如果有 就取消
const { data: infoRes } = await axios.get('http://localhost:8082/info', {
params: { name },
cancelToken: new axios.CancelToken(c=> {
cancel = c; // executor 函数接收一个 cancel 函数作为参数
})
});
setInfo({ ...infoRes })
console.log(infoRes);
}
return (
<>
<button onClick={() => { syncInfo('用户1') }}>测试1</button>
<button onClick={() => { syncInfo('用户2') }}>测试2</button>
<div>{JSON.stringify(info)}</div>
</>
)
}
export default App
参考:https://www.jianshu.com/p/fdd24f062cf5
如果是使用fetch
import { useState } from "react";
let syncInfoOldRequestController = null;
function App() {
const [info, setInfo] = useState({});
const syncInfo = async (name) => {
// 判断是否有老的请求控制器 如果有 终止请求
if (syncInfoOldRequestController) {
// 调用中止方法,发出信号,触发回调
// 可以监听此信号 controller.signal.addEventListener('abort', () => { console.log(signal.aborted); });
syncInfoOldRequestController.abort();
syncInfoOldRequestController = null;
}
// 请求要存入一个控制器
const controller = new AbortController(); // 创建 AbortController 实例
syncInfoOldRequestController = controller;
const infoRes = await fetch("http://localhost:8080/info?name=" + name, {
signal: controller.signal,
}).then((res) => res.json());
setInfo({ ...infoRes });
};
return (
<>
<button onClick={() => { syncInfo('用户1') }}>测试1</button>
<button onClick={() => { syncInfo('用户2') }}>测试2</button>
<div>{JSON.stringify(info)}</div>
</>
}
export default App;
理解
less中如何定义全局变量
vite项目中,可以根据vite提供的配置项修改
vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
css: {
preprocessorOptions: {
less: {
modifyVars:{
myColor: 'pink'
},
javascriptEnabled: true,
}
}
},
})
最后在任意的其它less文件中 使用即可
App.less
button {
color: @myColor;
}
当然 定义变量的时候也支持 读取一个变量文件 用法一样
vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import {resolve} from "path"
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
css: {
preprocessorOptions: {
less: {
modifyVars: {
hack: `true; @import (reference) "${resolve('src/var.less')}";`,
},
javascriptEnabled: true,
}
}
},
})
var.less
@color: blue;
如果是webpack,则也是需要配置即可,参考less-loader文档和less 全局变量文档
const path = require('path');
module.exports = {
mode: "development",
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.less$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
lessOptions: {
globalVars: {
myColor: 'red'
},
},
},
},
],
},
],
},
};
但是其本身不支持 导入less文件作为全局变量。 所以我们可以自己借助nodejs得fs去读取 然后遍历 拼接到globalVars里。
这里偷懒 找到网上已有得库,代码给扣下来了。
function getLessVariables(file) {
var themeContent = fs.readFileSync(file, 'utf-8')
var variables = {}
themeContent.split('\n').forEach(function(item) {
if (item.indexOf('//') > -1 || item.indexOf('/*') > -1) {
return
}
var _pair = item.split(':')
if (_pair.length < 2) return;
var key = _pair[0].replace('\r', '').replace('@', '')
if (!key) return;
var value = _pair[1].replace(';', '').replace('\r', '').replace(/^\s+|\s+$/g, '')
variables[key] = value
})
return variables
}
// webpack配置
globalVars: getLessVariables('./src/var.less')
如何将多为数组打散
es2022个数组的实例方法上加了个flat
。作用为扁平化数组,即将嵌套的数组分离出来变成一维数组。
// 用法 Array.flat(层级);
[1,2,[3,4]].flat(0);//不变
[1,2,[3,4]].flat(1);//变成 一维数组,这个1表示往外提取一层,即二维变成1维 默认为1
[1,2,[3,4]].flat(Infinity); // 不管几维数组 全给你提出来
// 示例
const arr = [1,[2,3],[[4],5]];
arr.flat(Infinity); // [1, 2, 3, 4, 5]
不过显然,如果面试问你这道题,你不能像上边那样回答,人家基本是让你自己实现的
const myFlat = (arr) => {
const res = [];
const handel = (param) => {
param.forEach(element => {
if(Array.isArray(element)){
handel(element)
}else{
res.push(element)
}
});
};
handel(arr);
return res;
};
const r = myFlat([1, [2, 3], [[4], 5]]);
console.log(r);
手写一个sleep函数
这个简单
const sleep = (timer)=>{
return new Promise((resolve)=>{
setTimeout(()=>{
resolve()
},timer)
})
}
react16.8中发生了什么大变化导致可以用hooks
css如何写出10号字体
大部分浏览器都得以最小字体设置在12px,我们可以通过设置浏览器来支持更小的字体。
如果要设置 更小字体 这可不是好办法,因为你无法修改用户浏览器设置。
css缩放
div{
font-size: 20px;
zoom: 0.5;
}
/** 首先自定义字号为12像素,因为浏览器支持的最小就是12像素,之后通过缩放来实现想要的字号:
** 10px = 10/12=0.8333333333333333
**/
div{
font-size: 12px;
transform: scale(0.83,0.83) ;
}
乾坤js遇到什么问题过吗
实现一个布局 左侧300px 右侧自适应
解释下flex:1代表什么意思
如何实现垂直居中 当align-item:center 什么轴
不同环境下 webpack或rollup等插件怎么按需加载 从而优化打包或启动速度
react如何实现vue那样的路由钩子 并监听后退,修改系统弹窗提示等