near / react-on-chain

Improved execution layer for NEAR decentralized frontend components
https://roc-docs.near.dev/
23 stars 5 forks source link

[Sandboxed mode] Passing a function that receives another function as a param in a prop leaves a "forever pending" promise. #424

Open pavelisnear opened 4 weeks ago

pavelisnear commented 4 weeks ago

Description

While working on https://github.com/near/bos-web-engine/issues/349 we've found a case when the a function is passes down to a child component with a param that is a function, can lead to a promise that is never resolved.

Example

Parent component

import { useState } from 'react';

import CallbackChildExample from './CallbackChildExample';

function CallbackExample() {
  const [value, setValue] = useState(0);

  return (
    <div style={{ padding: '10px' }}>
      <h1>Parent value: {value}</h1>
      <button onClick={() => setValue((x) => x + 1)}>
        Increment parent value
      </button>
      <CallbackChildExample
        // bwe={{ trust: { mode: 'trusted-author' } }}
        onClick={async (y) => {
          const val = await y(); // "forever pending" promise
          setValue((x) => x + val); // this line will never be executed
        }}
      />
    </div>
  );
}

export default CallbackExample as BWEComponent;

Child component

const Child = ({ onClick }) => {
  return (
    <div>
      <button
        onClick={() => {
          onClick(() => 2);
        }}
      >
        Increment value from the child
      </button>
    </div>
  );
};

export default Child as BWEComponent;