Don Rhummy
Don Rhummy

Reputation: 25830

How do I set a ref when using react.createElement?

I want to get a ref to the component represented by the element i create, but cannot get it to work. I tried this:

            var comp = React.createElement(
                MyComp,
                {
                    props: myprops,
                    ref: "mycomp"
                }
            );

But this doesn't work. How do i set a ref on it so the parent can call this.refs.mycomp.someMethod()?

Upvotes: 18

Views: 28922

Answers (3)

Indigo
Indigo

Reputation: 1

Also can use React.createRef in react>=16.3, like this:

    class ParentClass extends React.Component {
      constructor(props) {
        super(props)
    
        this.handleClick = this.handleClick.bind(this)
        // createRef here
        this.mycomp = React.createRef()
      }
    
      handleClick() {
        console.log(this.mycomp.current)
      }
    
      render() {
        const mycompProps = { something: '' }
        const mycomp = React.createElement(MyComp, { ...mycompProps, ref: this.mycomp })
    
        return <div onClick={this.handleClick}>This is Parant. {mycomp}</div>
      }
    }

Upvotes: 0

Kishor Gowda
Kishor Gowda

Reputation: 118

As of react v16.3, this.refs has been discouraged. One of the popular ways of doing it would be,

  const Comp = React.createElement(
                MyComp,
                {
                    props: myprops,
                    ref: ref => this.mycomp = ref
                }
            );

Upvotes: 7

dting
dting

Reputation: 39287

https://facebook.github.io/react/docs/top-level-api.html#react.createelement

ReactElement createElement(
  string/ReactClass type,
  [object props],
  [children ...]
)

The second parameter of the function is an optional props object for the component. Unless you want to refer to the props in the component as props.props you can splat the myProps object:

var comp = React.createElement(MyComp, { ...myprops, ref: "mycomp" });

class MyComp extends React.Component {
  constructor(props) {
    super(props);
    this.initialValue = props.initialValue;
    this.state = { value: this.initialValue };
    this.increment = this.increment.bind(this);
    this.reset = this.reset.bind(this);
  }
  
  increment() {
    this.setState({ value: this.state.value + 1 });
  }
  
  reset() {
    this.setState({ value: this.initialValue });
  }
  
  render() {
    return (
      <div className="child">
        <h1>Counter: {this.state.value}</h1>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.reset = this.reset.bind(this);
  }
  
  reset() {
    this.refs.mycomp.reset();
  }
  
  render() {
    const myProps = { initialValue: 1 };
    const Comp = React.createElement(MyComp, { ...myProps, ref: "mycomp" });
    return (
      <div className="parent">
        {Comp}
        <button onClick={this.reset}>Reset</button> Calls this.refs.mycomp.reset
      </div>
    );
  }
}

  
ReactDOM.render(<App />, document.getElementById('app'));
.parent {
  background-color: #555;
  color: #FFF;
  padding: 10px;
}

.child {
  background-color: #888;
  padding: 10px;
}

h1 {
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Upvotes: 11

Related Questions