filestack / filestack-js

Official Javascript SDK for the Filestack API and content ingestion system.
https://www.filestack.com
MIT License
206 stars 76 forks source link

Passing a React DOM node into the `container` option causes error "Converting circular structure to JSON" #464

Open cubeghost opened 2 years ago

cubeghost commented 2 years ago

The documentation mentions that PickerOptions' container param can take a string ID or a DOM Node. If this Node is a React element, Filepicker fails. It seems like React modifies its DOM Nodes slightly and as a result they're circular objects.

Expected Behavior

container: document.getElementById('drop') should behave the same as container: 'drop' when the element is a React node

Current Behavior

Creating the picker fails with an error similar to the following:

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'HTMLDivElement'
    |     property '__reactFiber$2ij0y8zcmy9' -> object with constructor 'FiberNode'
    --- property 'stateNode' closes the circle

Possible Solution

If possible, not stringifying this property

Steps to Reproduce (for bugs)

https://codesandbox.io/s/beautiful-ride-whblz?file=/src/App.js

Additional Screenshots

Context

I'd like to add a drop pane to a React component without using filestack-react

Your Environment

adriand commented 1 year ago

I had this issue as well and was not ultimately able to resolve the underlying problem of incompatibility with the node. However, I did manage to get this working as per the following steps.

I added a ref to the container, but also included an id:

<div ref={pickerRef} id="picker-container"></div>

Then at the top of the function (note: Typescript), I did the following:

const pickerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const client = filestack.init(props.filestackApiKey);
    const pickerOptions = {
      container: pickerRef.current?.id ?? undefined,
      displayMode: filestack.PickerDisplayMode.dropPane,
      dropPane: {
        overlay: false,
        onSuccess: function (res: any) {
          console.log(res);
        },
      },
    };
    client.setSecurity({
      policy: props.filestackPolicy,
      signature: props.filestackSignature,
    });
    client.picker(pickerOptions).open();
  }, [props.filestackApiKey, props.filestackPolicy, props.filestackSignature]);
BrentFarese commented 1 year ago

We're running into this now. There should be no reason the library needs to JSON.stringify the React node. Can this be fixed?