1

I'm trying to update the values of a multidimensional array with the values of a select input inside of a forEach loop. It's one array that holds two inner arrays. Every time I change the values with the select input, both inner arrays get updated. How can I get the inner arrays to update individually? codesandbox - https://codesandbox.io/s/multidimensional-array-3v6pmi

enter image description here

3 Answers 3

1

Update the state fxChoices considering it as a multi-dimentional array. Please refer the code-sandbox here.

Try to set the state as the value of each drop-down. Don't use the drop-down only to change the state, but use it to view the actual state that you've set.

Sign up to request clarification or add additional context in comments.

Comments

1

Organize your component like below. Now it's just a matter of changing NUMER_OF_INPUTS as many inputs you want.

const NUMER_OF_INPUTS = 2;

function App() {
  const [fxChoices, setFxChoices] = React.useState(
    Array.from({ length: NUMER_OF_INPUTS }).map(() => [[]])
  );

  console.log("fxChoices", fxChoices);

  const onChangeHandler = (compIndex, optionIndex, option) => {
    setFxChoices((prevState) =>
      prevState.map((item, itemIndex) => {
        if (itemIndex === compIndex) {
          const copyItem = [...item];
          copyItem[optionIndex] = option;
          return copyItem;
        }
        return item;
      })
    );
  };

  return (
    <div className="App">
      {Array.from({ length: NUMER_OF_INPUTS }).map((_, j) => {
        return (
          <div key={j}>
            <p>bus{j + 1}</p>
            <SelectComponent compIndex={j} onChangeHandler={onChangeHandler} />
          </div>
        );
      })}
    </div>
  );
}

const SelectComponent = ({ onChangeHandler, compIndex }) => {
  return Array.from({ length: 2 }).map((_, i) => (
    <div key={i} style={{ display: "flex", flexDirection: "column" }}>
      <select
        onChange={(e) => {
          onChangeHandler(compIndex, i, e.target.value);
        }}
        className="effect-select"
      >
        <option value={`bs${i + 1}-fx${i + 1}`}>{`FX${i + 1}`}</option>
        <option value="reverb">Reverb</option>
        <option value="delay">Delay</option>
        <option value="chorus">Chorus</option>
        <option value="chebyshev">Chebyshev</option>
        <option value="pitch-shift">PitchShift</option>
        <option value="compressor">Compressor</option>
      </select>
    </div>
  ));
};

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

NOTE: Try to think like building boxes when designing components.

Comments

1

Maybe it is easier to map you multidimensionnal array to access the indexes easily like below

   import { useState } from "react";
import "./styles.css";

export default function App() {
  const Options = () => {
    const [fxChoices, setFxChoices] = useState([...Array(2)].map(() => [...Array(2)].map(() => null)));
    console.log(fxChoices)
    return (<>
      {fxChoices.map((item, i) => (
      <div key={i}>
        <p>bus{i + 1}</p>
      <div style={{ display: "flex", flexDirection: "column" }}>
        {item.map((_, index) => <select
          onChange={(e) => {
            fxChoices[i][index] = e.target.value
            setFxChoices(fxChoices);
            console.log("fxChoices", fxChoices);
          }}
          className="effect-select"
        >
          <option value={`bs${i + 1}-fx${i + 1}`}>{`FX${i + 1}`}</option>
          <option value="reverb">Reverb</option>
          <option value="delay">Delay</option>
          <option value="chorus">Chorus</option>
          <option value="chebyshev">Chebyshev</option>
          <option value="pitch-shift">PitchShift</option>
          <option value="compressor">Compressor</option>
        </select>)}
      </div>
      </div>
      ))
      }
      </>
      );
  };
  return (
    <div className="App">
      <Options />
    </div>
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.