我正在学习React和Redux。我做了很多阅读并创建了一个基本的应用程序。我现在想要创建一个简单的计算器应用程序作为更高级的训练练习。
计算器应用程序将非常基本,即。数字和操作的按钮以及显示正在键入的数字或运行总计的简单文本字段。它将模拟一个简单的桌面计算器。也就是说,如果单击5按钮,文本字段中将出现5。如果现在单击6,则显示变为56.依次单击+,3,1,显示屏现在显示31.将显示Click =和87.
计算引擎(计算器)的业务逻辑是一项服务,可以与应用程序本身分开。应用程序中应该只有一个Calculator实例。我想知道的是如何使计算器可用于应用程序,尤其是。在减速器中。计算器需要保持一些状态,例如。到目前为止已输入的数字。
在React-Redux中,状态由单个对象表示,并通过商店提供。计算器应该是一个状态项吗? (另一项是要显示的当前值。)鉴于计算器永远不会改变,即。它总是指向相同的参考,这有意义吗? (计算器的内部状态会发生变化,但这对应用来说基本上是不可见的。)这是否意味着我的减速器总是会接受计算器作为状态并将其传回去?我不认为我每次都想制作副本。
或者通过某种Singleton使计算器更好?
还是有另外一种方法可以与React-Redux成语保持一致吗?
答案 0 :(得分:1)
我会想到像react / redux中的计算器这样的东西我会在我的reducer中创建一个用来处理' ='按下按钮,当前值和通过动作对象传入的表达式。我想要一个这样的减速器:
const initialState = {
totalValue: 0
};
export default function reducer(state = initialState, action = {}) {
switch (action.type) {
case EQUAL_PRESSED:
// Do your work here to call your calculator service.
// you can pass in action.currentTotal and action.expressionToEval
// to whatever functions will do the actual work and return a new
// total.
var newTotal = calcEngine(action.currentTotal, action.expressionToEval);
return {
...state,
totalValue: newTotal
};
}
}
export function equalPressed(currentTotal, expressionToEval) {
return {
type: EQUAL_PRESSED,
currentTotal: currentTotal,
expressionToEval: expressionToEval
};
}
然后在我的react组件中,我将访问redux状态树并获取新的totalValue
,以便在显示结果的任何位置显示。
答案 1 :(得分:1)
在使用Javascript(ES6)进一步阅读Singletons并在@jiujitsucoder的答案基础上进行阅读后,我提出了自己的解决方案,似乎运作良好。
Calculator类可作为应用程序其他组件的单例使用。
calculator.js
class Calculator {
constructor() {
this.runningTotal = 0;
}
currentValue() {
return this.runningTotal;
}
operation() { ... }
...
}
}
let instance = new Calculator();
export default instance
reducer(例如)接收与UI中的按键相对应的动作,并相应地指示计算器。
reducer.js
import Calculator from './calculator';
const initialValue = 0;
export default function(state = initialValue, action) {
switch (action.type) {
case PROCESS_DIGIT:
Calculator.digit(action.digit);
return Calculator.currentValue();
case PROCESS_OPERATOR:
Calculator.operator(action.operator);
return Calculator.currentValue();
}
return state;
}