简体   繁体   中英

How to change an array item value inside an object passed as state in React?

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;

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
      });
    }
  };

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;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM