usersina
usersina

Reputation: 1833

Setting a variable equal to a state updates the state on variable change

I ultimately want to create a copy of the state, update it accordingly without re-render then setState(myCopy) to trigger the View update. This question is better explained through code:

export default function App() {
   // Table Data
  const [tableState, setTableState] = useState({
    tableHead: ['Currency', 'Sell', 'Buy'],
    tableData: [
      ['USD', '1', '1'],
      ['EUR', '2', '2'],
      ['JPY', '3', '3'],
    ],
  });
  var newTableState = tableState;

  useState(() => {
    let rate1 = 15;
    let rate2 = 8;

    // * These 2 lines:
    newTableState.tableData[0][1] = rate1;
    newTableState.tableData[0][2] = rate2;
  },[])

  return(
   <View>
    <Text>{tableState.tableData[0][1]}</Text>
    <Text>{tableState.tableData[0][2]}</Text>
   </View>
  )
}

The two lines should only update newTableState. However, tableState is also being updated which updates the View. Is this the expected behaviour ?

I remember reading that updating a state directly without using setState is bad practice which is being done here in my opinion.

Here's a demonstrating snack.

Upvotes: 0

Views: 769

Answers (1)

Ioannis Potouridis
Ioannis Potouridis

Reputation: 1316

This is happening because you're not assigning the tableState itself but a reference to it. So updating newTableState means that you're mutating the state.

There are a couple of ways to do that, either by using lodash's cloneDeep

const newTableState = cloneDeep(tableState);

or by using JSON like this:

const newTableState = JSON.parse(JSON.stringify(tableState));

Upvotes: 1

Related Questions