Hello! I’m struggling with the calculator project and after many hours trying to fix it I really don’t understand what’s going on. Currently I have a numpad, an operators pad and two displays: one for showing the current input and the other to display the operation and will in the end display the output after evaluating. Codepen link
For easier understanding:
Components:
Components
const Display = (props) => {
return (
<div>
<div id="display" style={{ width: "400px", border: "1px solid red", height: "50px" }}>
{props.input}
</div>
<div id="display-output" style={{ width: "400px", border: "1px solid green", height: "50px" }}>
{props.output}
</div>
</div>
)
}
const NumPad = (props) => {
function handleNumPadClick(e) {
if (e.target.value == ".") {
props.addNewDecimal(e.target.value)
} else if (e.target.value == "0") {
props.addNewZero(e.target.value)
} else if (props.input.length == 1) {
props.addFirstNumber_dispatched(e.target.value)
} else {
props.addNewNumber(e.target.value)
}
}
return (
<div onClick={handleNumPadClick} style={{ width: "400px", border: "1px solid green", height: "50px" }}>
<button id="one" value="1">1</button>
<button id="two" value="2">2</button>
<button id="zero" value="0">0</button>
<button id="decimal" value=".">.</button>
</div>
)
}
const Operators = (props) => {
function handleOperatorsClick(e) {
props.addNewOperator(e.target.value)
}
return (
<div onClick={handleOperatorsClick} style={{ width: "400px", border: "1px solid blue", height: "50px" }}>
<button id="add" value="+">+</button>
</div>
)
}
class Presentational extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Display input={this.props.input} output={this.props.output} />
<NumPad input={this.props.input} addFirstNumber_dispatched={this.props.addFirstNumber_dispatched} addNewNumber={this.props.addNewNumber} addNewDecimal={this.props.addNewDecimal} addNewZero={this.props.addNewZero} />
<Operators addNewOperator={this.props.addNewOperator} />
</div>
)
}
}
Action creators: one for adding new number so it replaces the initial 0, two for 0 and . each,one for adding normal numbers and a last one for operators.
Action creators
const FIRST_NUMBER = 'FIRST_NUMBER'
const ADD_NUMBER = 'ADD_NUMBER'
const ADD_DECIMAL = 'ADD_DECIMAL'
const ADD_ZERO = 'ADD_ZERO'
const ADD_OPERATOR = 'ADD_OPERATOR'
//ACTION CREATOR
const addFirstNumber = (number) => {
return {
type: FIRST_NUMBER,
number: number
}
}
const addNumber = (number) => {
return {
type: ADD_NUMBER,
number: number
}
}
const addDecimal = () => {
return {
type: ADD_DECIMAL
}
}
const addZero = (number) => {
return {
type: ADD_ZERO,
number: number
}
}
const addOperator = (operator) => {
return {
type: ADD_OPERATOR,
operator: operator
}
}
Reducers, one for input the other one for output:
Reducers
var contains_decimal = (/\./)
const inputReducer = (state = '0', action) => {
switch (action.type) {
case FIRST_NUMBER:
return eval(parseInt(state + action.number))
case ADD_NUMBER:
return state + action.number
case ADD_DECIMAL:
if (contains_decimal.test(state)) {
return state
}
return state + '.'
case ADD_ZERO:
if (contains_decimal.test(state) || state != "0") {
return state + "0"
}
return state
case ADD_OPERATOR:
return action.operator
default:
return state
}
}
const outputReducer = (state = '', action) => {
switch (action.type) {
case FIRST_NUMBER:
return eval(parseInt(state + action.number))
case ADD_NUMBER:
return state + action.number
case ADD_DECIMAL:
if (contains_decimal.test(state)) {
return state
}
return state + '.'
case ADD_ZERO:
if (contains_decimal.test(state) || state != "0") {
return state + "0"
}
return state
case ADD_OPERATOR:
return state + action.operator
default:
return state
}
}
And mapping:
Mapping
function mapStateToProps(state) {
return ({
input: state.input,
output: state.output
})
}
function mapDispatchToProps(dispatch) {
return ({
addFirstNumber_dispatched: (number) => {
dispatch(addFirstNumber(number))
},
addNewNumber: (number) => {
dispatch(addNumber(number))
},
addNewDecimal: () => {
dispatch(addDecimal())
},
addNewZero: (number) => {
dispatch(addZero(number))
},
addNewOperator: (operator) => {
dispatch(addOperator(operator))
}
})
}
I ignored the connection and other stuff because I’m sure that works. But everything’s on the codepen.
The problem comes when I add an operator after a number and then another one but the operator gets replaced in the output, I really don’t have a clue why this is happening. This behavior doesn’t seem to occur when there’s a 0 after the operator but once I input a +[any_other_number] everything from the first operator gets replaced.
I know it’s a lot but any help would be greatly appreciated.