Tell us what’s happening:
I examined the boilerplate in a project file created with npm create-react-app --template redux. It included an example implementation of a counter app using the redux toolkit, a library not really addressed in the course material. I decided to have a go at it anyway and tried my best to mimic the boilerplate’s syntax with my calculator logic, being careful to rename and refactor each element of the boilerplate to fit my particular project. Specifically, it implemented something called a slice which, if I understand the docs correctly, should be automatically creating action creators and state-immutable reducer functions that correspond with the elements you declare in the reducers field of the slice object. Kinda sounded too good to be true and so far seems to be. Here’s the slice I currently have. The render element itself just has a bunch of css-arranged button elements and a display that call useDispatch(reducerElement) where reducerElement is an item in the reducers property of the slice.
Your code so far
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
display: '0',
currentOperand: null,
previousOperand: null,
currentOperator: null
};
export const calculatorSlice = createSlice({
name: 'calculator',
initialState,
reducers: {
getDisplay: (state) => {
return state.display;
},
enterDigit: (state, action) => {
if(state.display != '0'){
[...state.display].concat(action.payload);
} else {
state.display = action.payload;
}
state.currentOperand = parseFloat(state.display);
},
enterDecimal: (state) => {
if(state.display.includes('.') == false){
[...state.display].concat('.');
}
state.currentOperand = state.display;
},
add: (state) => {
if(state.currentOperand != null && state.previousOperand == null){
state.previousOperand = state.currentOperand;
state.currentOperand = 0;
state.display = '0';
} else if (state.previousOperand != null){
state.display = (state.previousOperand + state.currentOperand).toString();
state.currentOperand = state.previousOperand;
state.display = parseFloat(state.display);
} else { state.previousOperand = 0 }
state.currentOperator = '+';
},
subtract: (state) => {
if(state.currentOperand != null && state.previousOperand == null){
state.previousOperand = state.currentOperand;
state.currentOperand = 0;
state.display = '0';
} else if (state.previousOperand != null){
state.display = (state.previousOperand - state.currentOperand).toString();
state.currentOperand = state.previousOperand;
state.display = parseFloat(state.display);
} else { state.previousOperand = 0 }
state.currentOperator = '-';
},
multiply: (state) => {
if(state.currentOperand != null && state.previousOperand == null){
state.previousOperand = state.currentOperand;
state.currentOperand = 0;
state.display = '0';
} else if (state.previousOperand != null){
state.display = (state.previousOperand * state.currentOperand).toString();
state.currentOperand = state.previousOperand;
state.display = parseFloat(state.display);
} else { state.previousOperand = 0 }
state.currentOperator = '*';
},
divide: (state) => {
if(state.currentOperand != null && state.previousOperand == null){
state.previousOperand = state.currentOperand;
state.currentOperand = 0;
state.display = '0';
} else if (state.previousOperand != null){
state.display = (state.previousOperand / state.currentOperand).toString();
state.currentOperand = state.previousOperand;
state.display = parseFloat(state.display);
} else { state.previousOperand = 0 }
state.currentOperator = '/';
},
equals: (state) => {
if(state.currentOperand != null && state.previousOperand != null){
switch(state.currentOperator){
case '+': state.display = (state.previousOperand + state.currentOperand).toString();
state.currentOperand = parseFloat(state.display);
state.previousOperand = null;
break;
case '-': state.display = (state.previousOperand - state.currentOperand).toString();
state.currentOperand = parseFloat(state.display);
state.previousOperand = null;
break;
case '*': state.display = (state.previousOperand * state.currentOperand).toString();
state.currentOperand = parseFloat(state.display);
state.previousOperand = null;
break;
case '/': state.display = (state.previousOperand / state.currentOperand).toString();
state.currentOperand = parseFloat(state.display);
state.previousOperand = null;
break;
default: state.display = state.currentOperand.toString();
}
} else if (state.currentOperator != null && state.previousOperand == null){
state.display = state.currentOperand.toString();
} else { state.display = '0' }
state.currentOperator = null;
},
clear: (state) => {
state.display = '0';
state.currentOperand = null;
state.previousOperand = null;
state.currentOperator = null;
}
}
});
export const { getDisplay, enterDigit, enterDecimal, add, subtract, multiply, divide, equals, clear } = calculatorSlice.actions;
export const selectDisplay = (state) => state.display;
export default calculatorSlice.reducer;
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
Challenge: Build a JavaScript Calculator
Link to the challenge: