首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >UseReducer多次修改状态

UseReducer多次修改状态
EN

Stack Overflow用户
提问于 2021-01-24 03:46:38
回答 1查看 114关注 0票数 2

我想这是因为一个反模式的副作用。我从用户那里获得键盘输入,并使用它修改状态。最近,由于状态越来越复杂,我从useReducer钩子切换到useState。它对useState钩子起了很大作用。每个键盘输入都被多次打印到屏幕上。但不对状态进行键盘修改(从事件处理程序更改状态为非事件处理程序),不会显示多个呈现。

这是我的代码:

代码语言:javascript
运行
复制
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>
    )
}

减速机:

代码语言:javascript
运行
复制
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)
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-25 05:23:53

我没有技术知识,但它似乎反应不想有任何副作用,在与<React.StrictMode>。如果您有一个非原始数据类型。useReducer不会深入检查并看到它是同一个对象。避免变异对象,深入复制并返回更新的对象。这与setState类似。useState更好地处理变异对象。

修正:我重写了所有的方法,使其不可变。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65866955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档