Skip to content

Use functional approach without mutations? #1770

Open
@aryzing

Description

@aryzing

Problem

In reactive FE libraries like React, mutating deeply nested data can make it difficult to sync the UI with the data. For example, setting a new fee mutates the auth property,

setFee(amount: IntegerType) {
this.auth = setFee(this.auth, amount);
}

Even explicitly setting the data may not be sufficient,

function handleFeeChange(newFee) {
  transaction.setFee(newFee); // mutates inner prop
  setTransaction(transaction); // outer transaction object still has same ref. equality
}

Even after the above code, transaction has the same referential equality, which prevents memos from running or components from rendering.

Solution

Having a functional approach which avoids mutations would help with reactive UI frameworks.

The API could look something like,

const nextTransaction = setFee(transaction, newFee);

function setFee(transaction, newFee) {
  return {
    ...transaction,
    auth: createAuth({...transaction.auth, fee: newFee}),
  };
}

Workaround

Currently, the only way to preserve reactivity seems to be with something like

const [auth, setAuth] = useState(transaction.auth); // fee is stored in this object

function handleNewFee(newFee) {
  transaction.setFee(newFee);
  setAuth(transaction.auth);
}

return <div>{auth.fee}</div>

which is suboptimal since transaction is no longer the source of truth for fee, and it's all to easy to accidentally reach out for transaction.auth.fee in a reactive context and break the UI.

Metadata

Metadata

Assignees

Labels

featureBrand new functionality. New pages, workflows, endpoints, etc.

Type

No type

Projects

Status

📋 Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions