2

My issue is that when performing the blockSwap() function, the array itself does not seem to update as intended, but the hooks in the function update their state as expected. I am not sure how the state is updating appropriately when it is dependent on the array due to the indexOf() methods being used. I apologize if this is poorly worded, I have thoroughly confused myself trying to figure this out.

The intended result after firing the blockSwap() function is that the array elements would essentially trade places as well as the "block#Order"s.

The array should log as: "2","1". And the blockOrder should log as: 1 0.

const {useState} = React;

function BlockEditor() {
    let [block1Content, setBlock1Content] = useState("1");
    let [block2Content, setBlock2Content] = useState("2");

    let [block1Order, setBlock1Order] = useState(0);
    let [block2Order, setBlock2Order] = useState(1);
  
    let array = [block1Content, block2Content];

    function blockSwap() {
    [array[0], array[1]] = [array[1], array[0]];
    setBlock1Order(array.indexOf(block1Content));
    setBlock2Order(array.indexOf(block2Content));
  }
  
    function consoleLog() {
    console.log("array: ", array);
    console.log("blockOrder: ", block1Order, block2Order);
  }
  return (
    <div>
      <button onClick={blockSwap}>Swap Blocks</button>
      <button onClick={consoleLog}>Console Log Results</button>
    </div>
  )
}

ReactDOM.render(
  <BlockEditor/>,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="react"></div>

1 Answer 1

3

It's because you don't store the array in state. If you use useState for array too, it will work correctly:

const {useState} = React;

function BlockEditor() {
  let [block1Content, setBlock1Content] = useState('1');
  let [block2Content, setBlock2Content] = useState('2');

  let [block1Order, setBlock1Order] = useState(0);
  let [block2Order, setBlock2Order] = useState(1);

  let [array, setArray] = useState([block1Content, block2Content]);

  function blockSwap() {
    const copy = [...array];
    [copy[0], copy[1]] = [copy[1], copy[0]];
    setArray(copy);
    setBlock1Order(copy.indexOf(block1Content));
    setBlock2Order(copy.indexOf(block2Content));
  }

  function log() {
    console.log('array: ', array);
    console.log('blockOrder: ', block1Order, block2Order);
  }
  
  return (
    <div>
      <button onClick={blockSwap}>Swap Blocks</button>
      <button onClick={log}>Console Log Results</button>
    </div>
  );
}

ReactDOM.render(<BlockEditor />, document.getElementById('react'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="react"></div>

It would also work without creating a copy of the array:

  function blockSwap() {
    [array[0], array[1]] = [array[1], array[0]];
    setArray(array);
    setBlock1Order(array.indexOf(block1Content));
    setBlock2Order(array.indexOf(block2Content));
  }
Sign up to request clarification or add additional context in comments.

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.