[BUG] this.reactInstance =null on Form

1
closed
ivoscode
ivoscode
Posted 4 months ago

[BUG] this.reactInstance =null on Form #405

Environment

Please provide as many details as you can:

  • Hosting type
    • [] Form.io
    • Local deployment
      • Version: 5.1.1
  • Formio.js version: 4.14.0-rc.17
  • Frontend framework:Next.js 11.0.2
  • Browser: Chrome
  • Browser version: 92.0.4515.107 (Official Build) (arm64)

Expected behavior

I have a custom slider component. Using it in FormBuilder and expecting it to show up in Form and displaying data from submission if provided.

Observed behavior

Custom component works fine in the FormBuilder. It also shows up in Form and is able to submit data. The only problem I cannot set value from form submission, shows only the default value. In the FormBuilder the attachReact is returning an instance which is later needed by setValue function in ReactComponent.js. On the Form it does not. I believe that is a cause of the problem but not sure how to fix it.

Example

import { ReactComponent } from "@formio/react";
import React from "react";
import ReactDOM from "react-dom";
import settingsForm from "./Slider.settingsForm";

class SliderCustomComp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: props.value,
    };
  }
  setValue = (v) => {
    this.setState({ value: v }, () => this.props.onChange(this.state.value));
  };

  render() {
    return (
      <div className="w-full">
        <input
          className="w-full focus:outline-none"
          type="range"
          min={this.props.component.minRange}
          max={this.props.component.maxRange}
          value={this.state.value}
          onChange={(e) => {
            this.setValue(e.target.value);
          }}
        />
        <span>{this.state.value}</span>
      </div>
    );
  }
}

export default class Slider extends ReactComponent {
  constructor(component, options, data) {
    super(component, options, data);
  }

  static get builderInfo() {
    return {
      title: "Slider",
      icon: "sliders",
      group: "Data",
      documentation: "",
      weight: -10,
      schema: Slider.schema(),
    };
  }

  static schema() {
    return ReactComponent.schema({
      type: "sliderCustomComp",
      label: "Default Label",
    });
  }
  static editForm = settingsForm;

  attachReact(element) {
    const instance = ReactDOM.render(
      <SliderCustomComp
        component={this.component} // These are the component settings if you want to use them to render the component.
        value={this.dataValue} // The starting value of the component.
        onChange={this.updateValue} // The onChange event to call when the value changes.}
      />,
      element
    );
    console.log("instance in attachReact", instance);
    return instance;
  }

  /**
   * Automatically detach any react components.
   *
   * @param element
   */
  detachReact(element) {
    if (element) {
      ReactDOM.unmountComponentAtNode(element);
    }
  }
}

This is a console log from FormBuilder. I noticed it does not get the instance right away but it seems the error is causing to execute redraw function and it gets the instance. Screenshot 2021-08-05 at 15 09 58 On the Form it logs out Screenshot 2021-08-05 at 15 52 01

ivoscode
ivoscode
Created 2 months ago

Found a solution in case someone needs it. Getting instance via ref and then assigning to this.reactInstance.

attachReact(element) {
    let instance;
    ReactDOM.render(
      <SliderCustomComp
        ref={(refer) => {
          instance = refer;
        }}
        component={this.component} // These are the component settings if you want to use them to render the component.
        value={this.dataValue} // The starting value of the component.
        onChange={this.updateValue} // The onChange event to call when the value changes.}
      />,
      element,
      () => (this.reactInstance = instance)
    );

    
  }