【发布时间】:2021-01-24 03:46:38
【问题描述】:
我认为这是因为反模式的副作用。我从用户那里得到键盘输入并用它来修改状态。由于越来越复杂的状态,我最近从 useState 挂钩切换到 useReducer。它与 useState 挂钩效果很好。每个键盘输入都会多次打印到屏幕上。但是没有对状态进行键盘修改(不是来自事件处理程序的状态更改),不会显示多个渲染。
这是我的代码:
function TextBox() {
const AppState = {
/// Manages the state of the lines on the screen
line: [[]],
/// Line Index...
lIdx: 0,
/// Word Index...
wIdx: 0,
caretOn: false, timerOn: true, wordWrap: true,
}
const [state, dispatch] = useReducer(modifier, AppState)
/*
...
*/
return (
<div id="txtbox"
tabIndex="0"
ref = {txtBoxRef}
onKeyDown={(e) => dispatch({type: e.key})} >
<Lines linesProp={linesParam} />
</div>
)
}
减速机:
export default function modifier(state, action)
{
try {
/// Stops the caret from blinking...
const caretState = {
caretOn: true, timerOn: false, wordWrap: true,
}
let values = {
newLine: [], newLIdx: 0, newWIdx: 0
}
const set = val => ({...state, ...caretState, line: val.newLine,
lIdx: val.newLIdx, wIdx: val.newWIdx})
switch (action.type)
{
case "Backspace":
// Calls the Function that handles backspaces
// Declare new state values...
values = Backspace({ /// Modify state values...
line: state.line, lIdx: state.lIdx, wIdx: state.wIdx
})
/// Update state values...
return set(values)
case " ":
// Calls the fucntion that handles input from the spacebar
/// Modify state values...
values = spaceBar({line: state.line, lIdx: state.lIdx, wIdx: state.wIdx})
/// Update state values...
return set(values)
/* .... */
case "ArrowDown":
if (state.lIdx < state.line.length)
return { ...state, ...caretState, lIdx: state.lIdx + 1}
break;
case "Enter":
values = handleEnterKey({line: state.line, lIdx: state.lIdx, wIdx: state.wIdx})
return set(values)
case "text_wrap":
values = handleWrap ({line: state.line, lIdx: state.lIdx, wIdx: state.wIdx,
wordWrap: state.wordWrap})
return {...state, ...values}
case "hide-caret":
return {...state, caretOn: state.caretOn=false};
case "show-caret":
return {...state, caretOn: state.caretOn=true};
case "set-timer-on":
return {...state, timerOn: state.timerOn=true};
default:
/// Modify state values...
values = updateLine(action.type, state.line, state.lIdx, state.wIdx)
/// Update state values...
return set(values)
}
}
catch (e) {
console.info(e)
console.log(state)
}
}
【问题讨论】:
-
除了
show|hide-caret改变先前状态的动作(即caretOn: state.caretOn = false和caretOn: state.caretOn = true我没有看到任何其他明显的突变/副作用,但我们看不到任何你的实用函数正在做什么。你能包括Backspace、spaceBar、handleEnterKey、handleWrap、updateLine等......函数吗?
标签: reactjs