我想这是因为一个反模式的副作用。我从用户那里获得键盘输入,并使用它修改状态。最近,由于状态越来越复杂,我从useReducer钩子切换到useState。它对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)
}
}
发布于 2021-01-25 05:23:53
我没有技术知识,但它似乎反应不想有任何副作用,在与<React.StrictMode>
。如果您有一个非原始数据类型。useReducer不会深入检查并看到它是同一个对象。避免变异对象,深入复制并返回更新的对象。这与setState类似。useState更好地处理变异对象。
修正:我重写了所有的方法,使其不可变。
https://stackoverflow.com/questions/65866955
复制相似问题