反应& Redux - 部分状态会在不应该更新时更新?

时间:2017-09-21 21:15:29

标签: reactjs typescript redux

我是React-Redux-Typescript组合的新手,所以我需要一些帮助以及来自你们和gals的健全检查。我不在办公室ATM,所以提供的代码是从内存中动态写入的,它可能在语法上不正确,但请检查一般的想法/方法是否正确。我一回到办公室就会用适当的代码更新。在此之前,请假设我已经定义了适当的接口,类型以及导入和导出的所有内容。

考虑下面的状态示例。我遇到的问题是当我想要更新sections.firstSection.title时,initial.firstSection.title也会在不应该更新时使用相同的值进行更新,因为它没有在任何地方定义。为什么会这样?我的想法是保留初始状态,以便在需要重置输入字段中的值时引用它,例如。但随着它的更新,我最终得到了两个重复的分支。

州示例:

const initialState = {
    sections: {
        firstSection: {
            visible: true,
            enabled: true,
            changed: false,
            title: "Step one"
        },
        secondSection: {
            visible: true,
            enabled: true,
            changed: false,
            title: "Step two"
        }
    },
    initial: {
        firstSection: {
            visible: true,
            enabled: true,
            changed: false,
            title: "Step one"
        },
        secondSection: {
            visible: true,
            enabled: true,
            changed: false,
            title: "Step two"
        }
    }
}

const firstSectionData = {
    visible: true,
    enabled: false,
    changed: false,
    title: "First section"
}

initialState.sections.firstSection = firstSectionData;

初​​始化:

const store = createStore(rootReducer, initialState);
ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById(containerID) as HTMLElement
)

减速:

export function rootReducer(state: StoreState, action: Actions): StoreState {    
        let newState = {...state};
        switch(action.type){
            case action.UPDATE_FIRST:
                newState.sections.firstSection = updateSection(newState.sections.firstSection, action);
                break;
            case action.UPDATE_SECOND:
                newState.sections.firstSection = updateSection(newState.sections.secondSection, action);
               break;
            case action.RESET_FIRST:
                newState.sections.firstSection = resetSection(newState.sections.firstSection, action);
                break;
            case action.RESET_SECOND:
                newState.sections.secondSection = resetSection(newState.sections.firstSection, action);
               break;
            default:
                break;
        }
        return newState;
    }

    function updateSection(state: StoreState.Sections, action: Actions): StoreState.Sections {
        let newState = {...state};
        switch(action.type){
            case action.UPDATE_FIRST:
                newState.firstSection.title = action.value;
                break;
            case action.UPDATE_SECOND:
                newState.secondSection.title = action.value;
                break;
            default:
                break;
        }
        return newState;
    }

    function resetSection(state: StoreState, action: Actions): StoreState {
        let newState = {...state};
        switch(action.type){
            case action.RESET_FIRST:
                newState.sections.firstSection.title = newState.initial.firstSection.title;
                break;
            case action.RESET_SECOND:
                newState.sections.secondSection.title = newState.initial.secondSection.title;
                break;
            default:
                break;
        }
        return newState;
    }

操作:

function updateSection(type: string, value: string): StateUpdate {
    if(type == "first"){
            return {
                type: UPDATE_FIRST,
                value: value
            }
    } else if( type == "second" ) {
            return {
                type: UPDATE_SECOND,
                value: value
            }
   }
}

function resetSection(type: string, value: string): StateReset {
    if(type == "first"){
            return {
                type: RESET_FIRST,
                value: value
            }
    } else if( type == "second" ) {
            return {
                type: RESET_SECOND,
                value: value
            }
   }
}

急件:

function mapStateToProps(state: StoreState){
    return {
        firstSection: state.sections.firstSection,
        secondSection: state.sections.secondSection
    }
};

function mapDispatchToProps = (dispatch: Dispatch<Actions>){
    return {
        updateSection: (value: string) => {
            dispatch(updateSection(value))
        },
        resetSection: (value: string) => {
            dispatch(resetSection(value))
        }
    }
  };

  export default connect(mapStateToProps, mapDispatchToProps)(App)

应用组件

interface Props {
    firstSection: StoreState.Sections,
    secondSection: StoreState.Sections,
    updateSection: (value: string) => void,
    resetSection: (value: string) => void,
}

const App = (allProps: Props, action: Actions) => {
    const {firstSection, secondSection, updateSection, resetSection} = allProps;

    function expressUpdate(value?: string){
        updateSection("first", value);
    }

    function expressReset(value?: string){
        resetSection("second", value);
    }

    return(
        <div>
        <section>
            <ButtonField clickAction={expressReset} />
            <TextField text={firstSection.title} changeEvent={expressUpdate} />
        </section>
        <section>
            <ButtonField clickAction={expressReset} />
            <TextField text={secondSection.title} changeEvent={expressUpdate} />
        </section>
        </div>
    )
}

输入文本字段组件

interface Props {
    text: string;
    changeEvent: (value: string) => void;
}

function TextField(allProps: Props){
    const {text, changeEvent, ...props} = allProps;
    return(
        <input type="text" value={text} onChange={(e)=>changeEvent(e.currentTarget.value)} />
    )
}

我知道有很多东西需要消化,但我希望有人能够警告我可能犯的任何错误。 提前谢谢。

更新:好的,现在我已编辑代码以反映我真正使用的内容。

1 个答案:

答案 0 :(得分:0)

转换案件失败!

在上面的所有代码中都存在此问题。 Switch语句不是花哨的if/else语句。他们的工作方式不同。

输入switch语句时,您将跳转到与输入匹配的大小写。然后,您将继续通过开关案例,直到您点击break;命令,这将使您退出开关案例。

例如;

testSwitch = (x) => {

    switch(x) {
        case(1):
            console.log('one');
        case(2):
            console.log('two');
            break;
        case(3):
            console.log('three');
    }
}

testSwitch(1); // logs: 'one \n two'
testSwitch(2); // logs: 'two'
testSwitch(3); // logs: 'three'

您缺少break;语句会导致您的大部分代码行为都像testSwitch(1)