首页 > 解决方案 > 有没有办法将 React 事件移动到另一个文件然后导入它?

问题描述

我为 React 练习制作了一个计算器应用程序,我想知道是否可以重构此事件或将其移动到另一个模块,以便代码更有条理。

由于该事件已连接到 this.setState 我无法想出将其移动到另一个文件的方法。

是不是在这一点上我必须使用 Redux 之类的东西才能更轻松地组织我的活动?

onClickFunc(e){
    if(e.target.className === "number"){
        //Keep choosing firstValue if operator not set
        if(this.state.operator === null){
            this.setState({firstValue: e.target.value});
        }
        else{//If operator is set, add the second number
            this.setState({lastValue: e.target.value});
        }

    }
    else{
        //Can only think of a switch statement //e.target.innerHTML could have worked as well
        let call = this.state;
        switch(e.target.value){ 
            case '+':
                this.setState({
                    operator: function(x,y){return parseFloat(x)+parseFloat(y)}
                });
                break;
            case '-':
                this.setState({
                    operator: function(x,y){return parseFloat(x)-parseFloat(y)}
                });
                break;
            case 'X':
                this.setState({
                    operator: function(x,y){return parseFloat(x)*parseFloat(y)}
                });
                break;
            case '/':
                this.setState({
                    operator: function(x,y){return parseFloat(x)/parseFloat(y)}
                });
                break;
            case 'x^2':
                this.setState((value)=>{
                    return {firstValue: Math.pow(parseFloat(value.firstValue),2)}
                });
                break;
            case 'C':
                this.setState({firstValue:0,lastValue:0,operator:null});
                break;
            case '+-':
            //Make first number neg
                if(this.state.operator === null){
                    this.setState((value)=>{
                        return {firstValue: (-parseFloat(value.firstValue)) }
                    });
                }
                else{//Make last number neg
                    this.setState((value)=>{
                        return {lastValue: (-parseFloat(value.lastValue)) }
                    });
                }
                break;
            case '=':
                if(call.operator !== null){
                    let total = call.operator(call.firstValue,call.lastValue);
                    this.setState({firstValue: total});
                }
                break;
            default:
                this.setState({operator: null});
                console.log("failure");
        }
    }

}

标签: reactjsreduxrefactoring

解决方案


this.setState用于管理当前组件的状态。所以最好保持原样。

相反,您可以将每个操作员处理程序提取到单独的文件中(或提取到一个文件中,具体取决于您的要求和时间)。

handleNumbers = number => {
  this.state.operator === null
    ? this.setState({firstValue: number})
    : this.setState({lastValue: number});
}

handleOperators = operator => {
  this.setState({operator: operationMap(opreator)});
}

operatorHandlers = operator => handler => 

onClickFunc(e){
  e.target.className === "number"
    ? this.handleNumbers(e.target.value);
    : this.handleOperators(e.target.value);
}

您可以将操作实现移动到方法中并将它们移动到不同的文件并导出它们。

// You can move these to another file(s) and export each method.
const addHandler = (state, props) => (x, y) => parseFloat(x) + parseFloat(y);
const subtractionHandler = (state, props) => (x, y) => parseFloat(x) - parseFloat(y);
const multiplicationHandler = (state, props) => (x, y) => parseFloat(x) * parseFloat(y);
const operationMap = {
  "+": addHandler,
  "-": subtractionHandler,
  "X": multiplicationHandler
};

如果您查看这些*Handler方法,它们会采用(state, props).
目的是能够将操作符逻辑移到组件文件之外。

如果你想知道为什么,请查看Dan Abramov(核心 React 开发人员)的这篇推特。
他解释得最好。

丹·阿布拉莫夫 (Dan Abramov) 最保守的秘密

你可以通过更多的重构而发疯,但在有意义的时候这样做。
我可以考虑使用策略模式来使用高阶组件等注入策略(*处理程序方法)......


推荐阅读