超级面板
文章目录
最新文章
最近更新
文章分类
标签列表
文章归档

状态切换

切换状态是一个比较常见的操作,通常会这么进行切换:

常规操作

let state: boolean = true

function toggle(): boolean {
this.state = !this.state
return this.state
}

更通用一点的写法会进行一个封装:

class Switch {
private state:boolean

constructor(initState: boolean) {
this.state = initState
}

getState(): boolean {
return this.state
}

toggle(): boolean {
this.state = !this.state
return this.getState()
}
}

更改状态的表示方法

如果是文字状态切换呢?可能会这么写:

const switcher = new Switch(false)

let currentState = switcher.getState()
currentState ? 'on' : 'off'

或许你会想到可以更改 Switch 的定义:

class Switch {
private state: boolean
private trueState: string
private falseState: string

constructor(initState: boolean, trueState: string, falseState: string) {
this.state = initState
this.trueState = trueState
this.falseState = falseState
}

toggle(): boolean {
this.state = !this.state
return this.getState()
}

getState(): boolean {
return this.state
}
}

切换多个状态

在有些场合,会有有多个状态进行切换,比如十字路口的灯有红黄绿三种状态切换,这个时候应该想到可以使用数组。

这里直接一步到位,使用泛型,支持任意的状态类型切换:

class Switch<T> {
private index: number
private state: T[]
constructor(initState: T, state: T[]) {
this.state = state
this.index = state.indexOf(initState)
}
getState(): T {
return this.state[this.index]
}
toggle(): T {
this.index = (this.index + 1) % this.state.length
return this.getState()
}
}

const switcher = new Switch('红', ['红', '黄', '绿'])
console.log(switcher.toggle()) // 黄
console.log(switcher.toggle()) // 绿
console.log(switcher.toggle()) // 红

使用泛型,当然也支持函数,比如根据不同的状态执行不同的操作:

const redFn = () => console.log('红灯,禁止通行')
const yellowFn = () => console.log('黄灯,谨慎通行')
const greenFn = () => console.log('绿灯,畅通无阻')
const roadSwitcher = new Switch(redFn, [redFn, yellowFn, greenFn])
roadSwitcher.getState()() // 红灯,禁止通行
roadSwitcher.toggle()() // 黄灯,谨慎通行
roadSwitcher.toggle()() // 绿灯,畅通无阻
roadSwitcher.toggle()() // 红灯,禁止通行

高阶函数

除了使用类,使用高阶函数也是可以做到的:

function switchFn<T>(initState: T, state: T[]) {
let index: number = state.indexOf(initState)
return function() {
index = (index + 1) % state.length
return state[index]
}
}

const switcher = switchFn('红', ['红', '黄', '绿'])
console.log(switcher()) // 黄
console.log(switcher()) // 绿
console.log(switcher()) // 红
console.log(switcher()) // 黄

const redFn = () => console.log('红灯,禁止通行')
const yellowFn = () => console.log('黄灯,谨慎通行')
const greenFn = () => console.log('绿灯,畅通无阻')
const roadSwitcher = switchFn(redFn, [redFn, yellowFn, greenFn])
roadSwitcher()() // 黄灯,谨慎通行
roadSwitcher()() // 绿灯,畅通无阻
roadSwitcher()() // 红灯,禁止通行
roadSwitcher()() // 黄灯,谨慎通行

生成器 Generator

遍历多个状态时,也可以使用 Generator

function *loop<T>(initIndex: number, list: T[]){
let currentIndex: number = initIndex

while(true){
currentIndex = (currentIndex + 1) % list.length
yield list[currentIndex]
}
}

function switchFn<T>(initState: T, state: T[]) {
const list = loop(state.indexOf(initState), state)
return function() {
return list.next().value as T
}
}

自定义 hook

const useSwitch = <T extends unknown >(initialValue: T, stateList: T[]): [T, () => void] => {
const switcher = switchFn(initialValue, stateList);
const [state, setState] = useState<T>(switcher(false));

return [state, () => {
setState(switcher(true));
}];
}