0

This question is for someone very good with react as well as understand filestack-js

I read the whole source code for src/ReactFilestack.jsx but I can't find the part where filestack attach itself to the dom.. somehow it just magically .. did without using ref or ReactDom whatsoever.

if possible anyone can point me to the line that the dom attachment from client to <Tag> happens?https://github.com/filestack/filestack-react/blob/master/src/ReactFilestack.jsx

Thanks!

import React, { Component } from 'react';
import filestack from 'filestack-js';
import PropTypes from 'prop-types';

class ReactFilestack extends Component {
  static defaultProps = {
    file: null,
    link: false,
    buttonText: 'Pick file',
    buttonClass: '',
    onSuccess: result => console.log(result),
    onError: error => console.error(error),
    mode: 'pick',
    options: {},
    security: null,
    children: null,
    render: null,
    cname: null,
  };

  static propTypes = {
    file: PropTypes.objectOf(PropTypes.any),
    apikey: PropTypes.string.isRequired,
    link: PropTypes.bool,
    mode: PropTypes.string,
    buttonText: PropTypes.string,
    buttonClass: PropTypes.string,
    onSuccess: PropTypes.func,
    onError: PropTypes.func,
    options: PropTypes.objectOf(PropTypes.any),
    security: PropTypes.objectOf(PropTypes.any),
    children: PropTypes.node,
    render: PropTypes.func,
    cname: PropTypes.string,
  };

  onClickPick = (event) => {
    event.stopPropagation();
    event.preventDefault();
    const {
      apikey,
      onSuccess,
      onError,
      options,
      mode,
      file,
      security,
      cname
    } = this.props;
    const onFinished = (result) => {
      if (typeof onSuccess === 'function') {
        onSuccess(result);
      } else {
        console.log(result);
      }
    };
    const onFail = (error) => {
      if (typeof onError === 'function') {
        onError(error);
      } else {
        console.error(error);
      }
    };

    this.initClient(mode, apikey, options, file, security, cname)
      .then(onFinished)
      .catch(onFail);
  };

  initClient = (mode, apikey, options, file, security, cname) => {
    const { url, handle } = options;
    delete options.handle;
    delete options.url;
    const client = filestack.init(apikey, security, cname);

    if (mode === 'transform') {
      return new Promise((resolve, reject) => {
        try {
          resolve(client.transform(url, options));
        } catch (err) {
          reject(err);
        }
      });
    } else if (mode === 'retrieve') {
      return client.retrieve(handle, options);
    } else if (mode === 'metadata') {
      return client.metadata(handle, options);
    } else if (mode === 'storeUrl') {
      return client.storeURL(url, options);
    } else if (mode === 'upload') {
      return client.upload(file, options);
    } else if (mode === 'remove') {
      return client.remove(handle, security);
    }

    return client.pick(options);
  };

  render () {
    const { buttonClass, buttonText, link, children, render: CustomRender } = this.props;
    if (CustomRender) {
      return (
        <CustomRender onPick={this.onClickPick} />
      );
    }
    const Tag = link ? 'a' : 'button';
    return (
      <Tag
        name="filestack"
        onClick={this.onClickPick}
        className={buttonClass}
      >
        {children || buttonText}
      </Tag>
    );
  }
}

export default ReactFilestack;
ey dee ey em
  • 7,991
  • 14
  • 65
  • 121
  • What do you mean by the dom attachment? – Axnyff Jan 03 '18 at 16:00
  • @Axnyff meaning, once the dom is created by the `client`, it should somehow attached to some existing dom to make it show in the view? or am I understanding it incorrectly? – ey dee ey em Jan 03 '18 at 16:00
  • Not sure I'm understanding. Can you provide an example of the usage of this component and what you don't understand? – Axnyff Jan 03 '18 at 16:03
  • I am sorry, this question is really for someone understand filestack-js, which is rather hidden for its core code `loader` which source code is not showing to the public. that's why I had to post a SO question instead... But just for what it worth, if you create a dom with regular js, one need to attach the created dom into the jsx dom, in order to let it show. that can be googled anywhere – ey dee ey em Jan 03 '18 at 16:05
  • and an example, for wiw https://codepen.io/Filestack/pen/cb18b66fff43a8c22d834d5186228e22 – ey dee ey em Jan 03 '18 at 16:07
  • So you just want to know how the drag and drop part is added to the DOM? That's the render part of the FileStack component, you just need to include somewhere in your application. – Axnyff Jan 03 '18 at 16:09
  • Looking at the code and the docs, it appears that when triggering an action filestack will append a `div` to the dom and put its UI in it. The UI displays as a modal and there is no way to mount it within a react component using the package you linked. Nowadays they could use portals to make the UI a child of its parent react component. – adz5A Jan 03 '18 at 16:25
  • @adz5A good point! I still dont see where it got somehow mounted to react? Or what you saying is ... it actually just creating a whole new dom that is no way associated with react? Gotcha... – ey dee ey em Jan 03 '18 at 19:06
  • 1
    you can observe this behavior by looking in the Dom inspector. you should see a div appear in the bottom of the document. it did not create a 'dom' but only a dom element and mounted their ui on it. – adz5A Jan 03 '18 at 19:18
  • @adz5A hey man should should turn your comment into an answer with any detail you want to add, thanks I will mark it – ey dee ey em Feb 01 '18 at 19:56

1 Answers1

0

Looking at the code and the docs, it appears that when triggering an action filestack will append a div to the dom and put its UI in it. The UI displays as a modal and there is no way to mount it within a react component using the package you linked.

Nowadays they could use portals to make the UI a child of its parent react component.

This behaviour can be observed by looking in the Dom inspector. You should see a div appear in the bottom of the document. It did not create a 'dom' but only a dom element and mounted their ui on it.

adz5A
  • 2,012
  • 9
  • 10
  • btw I think I missed previous waht you mean by `portal`? – ey dee ey em Feb 13 '18 at 17:59
  • 1
    this is a new feature of react 16 which allows to mount a react component on a new dom node, much like reactDom.render. the use case is for child component that must be appended to specific places in the Dom, like modals for instance. – adz5A Feb 13 '18 at 18:12