Reputation: 171
I have an React application, all my components are functional and I'm using useState
hook to manage the state. I'm passing the state as an single object, as showed below:
const initialState = {
displayValue: "0",
values: [0, 0],
current: 0,
operation: null,
shouldClearDisplay: false,
};
const [state, setState] = useState({ ...initialState });
I can change the state of displayValue
as showed below:
setState({...state, displayValue: "0"})
The problem is when I try to change the value of values
. What I trying to do is this:
const addDigit = (digit) => {
if (state.shouldClearDisplay) {
setState({ ...state, values[current]: displayValue , displayValue: digit, shouldClearDisplay: false });
return;
}
But when I try to do this values[current]: displayValue
, it gives a sintax error: SyntaxError: /path/to/component/Calculator.jsx: Unexpected token, expected "," (22:33)
. It seems that I can't update the value of an array inside an object that way.
How can I achieve this?
EDIT 01:
Below the entire content of Calculator.jsx
:
import React, { useState } from "react";
import CalcButton from "./CalcButton";
import Display from "./Display";
const Calculator = (props) => {
const initialState = {
displayValue: "0",
values: [0, 0],
current: 0,
operation: null,
shouldClearDisplay: false,
};
const [state, setState] = useState({ ...initialState });
const resetState = () => {
setState({ ...initialState });
};
const addDigit = (digit) => {
if (state.shouldClearDisplay) {
setState({ ...state, values[state.current]: displayValue , displayValue: digit, shouldClearDisplay: false });
return;
}
if (state.displayValue === "0") {
setState({ ...state, displayValue: digit });
return;
}
if (digit === "0" && state.displayValue === "0") {
return;
}
setState({ ...state, displayValue: state.displayValue + digit });
};
const setOperation = (op) => {
setState({ ...state, shouldClearDisplay: true, operation: op });
};
const c = {
lightGray: "#d7d9ce",
darkGray: "#8e9aa4",
orange: "#fc7536",
black: "#010f14",
};
return (
<React.Fragment>
<Display bgColor={c.black} value={state.displayValue} />
<div className="d-flex">
<CalcButton
text="AC"
width="180px"
passedOnClick={resetState}
bgColor={c.lightGray}
/>
<CalcButton text="÷" passedOnClick={setOperation} bgColor={c.orange} />
</div>
<div className="d-flex">
<CalcButton text="7" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="8" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="9" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="X" passedOnClick={setOperation} bgColor={c.orange} />
</div>
<div className="d-flex">
<CalcButton text="4" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="5" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="6" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="-" passedOnClick={setOperation} bgColor={c.orange} />
</div>
<div className="d-flex">
<CalcButton text="1" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="2" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="3" passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="+" passedOnClick={setOperation} bgColor={c.orange} />
</div>
<div className="d-flex">
<CalcButton
text="0"
passedOnClick={addDigit}
width="120px"
bgColor={c.lightGray}
/>
<CalcButton text="." passedOnClick={addDigit} bgColor={c.lightGray} />
<CalcButton text="=" passedOnClick={setOperation} bgColor={c.orange} />
</div>
</React.Fragment>
);
};
export default Calculator;
Upvotes: 0
Views: 58
Reputation: 777
You should calculate your state first and then update it
const [state, setState] = useState(initialState);
const addDigit = (digit) => {
if (state.shouldClearDisplay) {
let temp = [...state.values];
temp[state.current] = state.displayValue;
setState({
...state,
values: temp,
displayValue: digit,
shouldClearDisplay: false
});
}
};
Upvotes: 1
Reputation: 2039
Create a new array where element at current
index is displayValue
. Then assign this array to values
.
A simple example would be like this
const addDigit = (digit) => {
if (state.shouldClearDisplay) {
setState({
...state,
values: state.values.map((v,i) => i===state.current ? displayValue : v),
displayValue: digit,
shouldClearDisplay: false
});
return;
}
}
Upvotes: 0