Skip to content

前端开发-从夯实基础到突破瓶颈

为什么不能直接在 JSX 中使用 if...else 条件渲染,而只能借用函数逻辑实现呢?

我们可以在 JSX 中使用三目运算符来实现条件渲染,但是过于复杂的情况下我们就需要使用函数逻辑来实现。避免出现三目地域

主要原因是 JSX 会被编译成React.createElement,而React.createElement的底层逻辑是无法运行 JavaScript 代码的,只能渲染出一个结果,因此,JSX 中除了 JavaScript 表达式(三目运算符就是表达式)不能直接写 JavaScript 的语法

this.setState 都是异步更新的吗?

相信绝大多数开发者和我一样,都会普遍认为 react 中,this.setState 是异步更新的。但是很遗憾这个结论是错误的......

我们来看下 react 官方的一个解释:

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.

传送门

总结下来呢,就是是由 react 自行控制的的时间处理中,this.setState是不会立即更新,而如果是 react 控制之外的情况下操作this.setState,这时候就是会立即更新!

demo

tsx
export default function SetStateDemo() {
	const [number, setNumber] = useState(0)

	const addNumber = () => {
		const newValue = number + 1
		setNumber(newValue)
		console.log(number)
	}

	useEffect(() => {
		document
			.getElementById('outside_react')
			?.addEventListener('click', addNumber)
	}, [])

	useEffect(() => {
		console.log('变化了')
	}, [number])

	return (
		<div>
			<p>当前值:{number}</p>
			<button onClick={addNumber}>react控制</button>
			<br />
			<button id="outside_react">非react控制</button>
		</div>
	)
}
export default function SetStateDemo() {
	const [number, setNumber] = useState(0)

	const addNumber = () => {
		const newValue = number + 1
		setNumber(newValue)
		console.log(number)
	}

	useEffect(() => {
		document
			.getElementById('outside_react')
			?.addEventListener('click', addNumber)
	}, [])

	useEffect(() => {
		console.log('变化了')
	}, [number])

	return (
		<div>
			<p>当前值:{number}</p>
			<button onClick={addNumber}>react控制</button>
			<br />
			<button id="outside_react">非react控制</button>
		</div>
	)
}

CMD 与 ESM 的区别

这是一个比较经典的一个面试题,大家多少也能够回答的出来一些内容,大致也是围绕着如下几个点回答:

  • CMD 是用于服务端(node.js)端,ESM 用于浏览器端

  • ESM 是静态化,这样才能保证在编译时就能够确定各个模块的依赖关系,而 CMD 或者 AMD 是只有在运行时才能确定

    这是为什么 ESM 每次都会结合 tree-shaking 展开一起讨论的原因

  • ESM 输出的是值的引用,而 CMD 输出的是值的拷贝!

  • ......

其他的点大家可以自行补充,但是第三点关于值的引用和拷贝是一个重要的点,这点可以看如下案例:

ESM

js
// data.js
export let user = 'jimmy'
export function changeData() {
	user = 'xuexue'
}

// index.js
import { user, changeData } from './data.js'

console.log('before: ', user) // jimmy
changeData()
console.log('change after: ', user) // xuexue
// data.js
export let user = 'jimmy'
export function changeData() {
	user = 'xuexue'
}

// index.js
import { user, changeData } from './data.js'

console.log('before: ', user) // jimmy
changeData()
console.log('change after: ', user) // xuexue

CMD

js
// data.js
let user = 'jimmy'

const changeData = () => {
	user = 'xuexue'
}

module.exports = {
	user,
	changeData,
}

// index.js
const user = require('./data').user
const changeData = require('./data').changeData

console.log('before: ', user) // jimmy
changeData()
console.log('change after: ', user) // jimmy
// data.js
let user = 'jimmy'

const changeData = () => {
	user = 'xuexue'
}

module.exports = {
	user,
	changeData,
}

// index.js
const user = require('./data').user
const changeData = require('./data').changeData

console.log('before: ', user) // jimmy
changeData()
console.log('change after: ', user) // jimmy

浏览器缓存机制

浏览器的资源缓存可以分为硬盘缓存和内存缓存两种,当用户首次访问网页时,如果资源文件呗缓存在内存中,同时也会缓存一份到本地的磁盘中。

  • 当用户刷新页面时,会判断内存中缓存的资源是否有过期,如果没有过期,则是可以直接从内存中读取数据并直接加载。

  • 当用户关闭网页再次重新进入这个页面时,这时候就会从硬盘缓存中判断数据是否有过期,如果没有过期,就可以直接从本地磁盘缓存中读取数据,并再次缓存到内存中

流程图

常见文件的缓存机制

有错欢迎指出和新增

  • http 请求头报文各种字段 e-tagif-modified-since 等等
  • 文件哈希,如打包工具打包出来的文件都带有哈希值,也可以根据哈希值判断文件是否过期
  • ...