Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    REACT <Button ref={...} bug

    I’m trying to use a ref with a Button component, but myRef.current is always null.
    Interestingly, if I do the same thing with a MenuItem, the ref works as expected.

    I found a workaround that allows refs to work. I modified the __createSCInstance function in ReactComponent.js like this:
    Code:
    __createSCInstance(className, config) {
        for (let prop of this.REACT_PROPS) delete config[prop];
    
        if (!config.children && config.childComponents) {
            config.children = config.childComponents;
        }
    
        // ***************begin workaround for refs
        const created = isc[className].create(config);
        if (this.props && this.props.REF) {
            const r = this.props.REF;
            if (typeof r === "function") {
                r(created);
            } else {
                r.current = created;
            }
        }
        //***************** end workaround for refs
        return created;
    }
    Then, in my project, I create the button like this:
    Code:
    <Button
        REF={this.loadButton}
        title={Strings.get("load")}
        disabled="true"
        click={this.loadData.bind(this)}
    />
    I’m confident that you’ll find a more elegant solution that allows using the standard React ref.

    PS:
    I noticed that the ref works for both <MenuItem> and <Button>, but only in this case:
    Code:
    render() {
        return (
            <>
                <Button {...Properties.getButton()}
                    ref={this.loadButton}
                    title={Strings.get("load")}
                    disabled="true"
                    click={this.loadData.bind(this)}
                />
            </>
        );
    }
    However, if I do it like this:
    Code:
    render() {
        let owner = this;
        return (
            <VLayout>
                <Button {...Properties.getButton()}
                    ref={this.loadButton}
                    title={Strings.get("load")}
                    disabled="true"
                    click={this.loadData.bind(this)}
                />
            </VLayout>
        );
    }
    then ref.current is null.
    Last edited by Hirn; 28 Sep 2025, 11:43.

    #2
    While fixing refs for nested components, we found an unrelated problem affecting ReactComponent.getSCComponent() (shown in our documentation for refs). Even when refs are fixed for nested components, getSCComponent() does not return the live SmartClient widget. We are fixing this as well, but can you confirm how you are using the ref? Are you calling getSCComponent()?

    Comment


      #3
      My changes add a reference to the created ISC component,
      so myRef.current points to the actual component rather than the React wrapper where you’d have to call getSCComponent().

      Code:
      // ***************begin workaround for refs
          const created = isc[className].create(config);
      //-----------------------------------------
          if (this.props && this.props.REF) {
              const r = this.props.REF;
              if (typeof r === "function") {
                  r(created);
              } else {
                  r.current = created;
      //-----------------------------------------
              }
          }
      //***************** end workaround for refs

      Comment


        #4
        Our fix will restore native refs, which means the documented approach of using getSCComponent() is required. This is actually preferable because in some situations the SC widget may be rebuilt while keeping the same React component. For example, see the notes on property recreateOnReactComponentUpdate in the Using SmartClient with React help topic.

        Comment


          #5
          Wouldn’t ReactComponent.__createSCInstance be called when recreateOnReactComponentUpdate is triggered?
          If so, then there’s no issue with updating the ref.
          And for those already using getSCComponent(), you could just add:
          Code:
          instance.getSCComponent = function() {
              return this;
          };
          Last edited by Hirn; 30 Sep 2025, 20:28.

          Comment


            #6
            We'd rather provide support for native React refs for nested React components, as this is most consistent with expectation and also how others have handled React integration.

            The required fixes have been committed and should be available in today's builds of SC 13.1 and newer releases, dated 2025-10-01. Hopefully, these fixes will provide the access you need.

            Comment


              #7
              Everything works like clockwork.
              Thank you very much.

              Comment

              Working...
              X