reactjsreact-hookscarbon-design-system

How to update an object key value based on other key value in Array of object in React?


I need to understand how we can update an object key value based on other key value in Array of object in React. Let' assume I have two different input field which is somehow link with the below formatted object, this object basically responsible for changing behavior of graph whenever I type something in input field. The below object passed into Graph component to show the changes whenever we type something in 2 input field.

import React, {useState} from "react";
import ReactDOM from "react-dom";
import { GaugeChart } from "@carbon/charts-react";
import "@carbon/charts/styles.css";

// in the data object graph behavior will update based on 
input provided in two input field and that will happen based on group key value

    const graphObj = {
        data: [
            {
                "group": "value",
                "value": 40
            },
            {
                "group": "delta",
                "value": 1000
            }
        ],
            options: {
            "resizable": true,
            "height": "250px",
            "width": "100%",
            "gauge": {
                "type": "semi",
                "status": "danger"
            }
        }
        };

const App = () => {
    
    const [graph, setGraph] = useState(graphObj); 
    const [formData, setFormData]  = useState({
        min: 40,
        max: 1000
    })

    const handleChange = (e) => {
        
    }

 return (
        <>
        <GaugeChart
            data={graph.data}
            options={graph.options}>
        </GaugeChart>
        <br />
        <form>
            <input value={formData.min} onChange={handleChange}  />
            <input value={formData.max} onChange={handleChange}/>
        </form>
        </>
    );
}

export default App;

ReactDOM.render(<App />, document.getElementById("root"));

Solution

  • Assuming that min in your state is value and max is delta, I would refactor a bit. Since your graphObj is a constant that we just want to add the formData to we can use useMemo that we remake the graphOptions object everytime form data updates.

    import React, { useState, useMemo } from "react";
    import ReactDOM from "react-dom";
    import { GaugeChart } from "@carbon/charts-react";
    import "@carbon/charts/styles.css";
    
    const graphObj = {
      data: [
        {
          group: "value",
          value: 40,
        },
        {
          group: "delta",
          value: 1000,
        },
      ],
      options: {
        resizable: true,
        height: "250px",
        width: "100%",
        gauge: {
          type: "semi",
          status: "danger",
        },
      },
    };
    
    const App = () => {
      const [formData, setFormData] = useState({
        value: 40,
        delta: 1000,
      });
    
      const handleChange = (e) => {
        const { name, value } = e.target;
        // update the form data
        setFormData({ ...formData, [name]: value });
      };
    
      // add form data to graph object
      const graphData = useMemo(() => {
        // formdata to { group: key, value: value } type
        return Object.keys(formData).map((key) => ({
          group: key,
          value: formData[key],
        }));
      }, [formData]);
    
      return (
        <>
          <GaugeChart data={graphData} options={graphObj.options}></GaugeChart>
          <br />
          <form>
            <input name={"value"} value={formData.value} onChange={handleChange} />
            <input name={"delta"} value={formData.delta} onChange={handleChange} />
          </form>
        </>
      );
    };
    
    export default App;