user2998285
user2998285

Reputation: 15

Binding methods in react components

I'm getting an error when I try to bind values to the component function handleInput: Uncaught TypeError: Cannot read property 'bind' of undefined

However, when I insert the input element into the return statement at the bottom of the render method, it doesn't produce any errors. I'm guessing that this has something to do with the lifecycle of the render method, but I'm not sure.

Any insight is appreciated.

As for what the code does, it retrieves a string from this.props.info.text and replaces all instances of <= var[0-9] => with an html input box, then appends to a div. On user input, the values are propagated to a parent component.

export default class Line extends React.Component {

 constructor() {
   super();
 }

 handleInput(id, e) {
   console.log(id);
   this.props.handleCode(e.target.value);
 }

 shouldComponentUpdate(){
   if (document.getElementById('otherClass').innerHTML.length == 0){
     return true;
   }
   return false;
 }

 render() {
   var id = this.props.id;
   let codeVal = "";
   let codeDiv = document.createElement('div');
   if (typeof(this.props.info) !== 'undefined') {
     //breaks here
     codeVal = this.props.info.text.replace(/<= var[0-9] =>/, '<input type="text" onInput=this.handleInput.bind(this,id)></input>');
     let index = codeVal.indexOf('<');
     let splits = [codeVal.slice(0, index), codeVal.slice(index)];
     codeDiv.innerHTML = "<div class='row'><div class='col-md-6'>"+splits[0]+"</div><div class='col-md-6'>"+splits[1]+ "</div></div>";
     document.getElementById('otherClass').appendChild(codeDiv);
   }

   return(
     <div id='otherClass'></div>
   );

 }
}

Parent code:

export default class StateVal extends React.Component {
  handleCode(id, e){
    console.log("value propagated on user input");
    alert(e);
  }
  render() {
    return (
     <div className="col-md-6">
       <div className="card-block">
        < Line info={this.props.data.codeBody[0]} handleCode={this.handleCode} id={1} />
     </div>
   </div>
  );
}
}

Edit: the idea is that if I retrieve a text value through props like "int value = <=var0=>" how can I convert it to a responsive html input tag like

 int value = <input type='text' onInput=this.handleInput.bind(this, id)/>

and then render it in html

Upvotes: 1

Views: 566

Answers (3)

Damien Leroux
Damien Leroux

Reputation: 11693

You can only write valid HTML when generating Html from a string with react.

<input type='text' onInput=this.handleInput.bind(this, id)/> is not valid: onInput is not a HTML valid props

Generating a jsx string to HTML with react is a special case requiring babel.

I don't think you'll be able to insert jsx string in a component on the fly using a string but there is may be another solution. Split your string into an array and replace matching string by not a string code "<../>" but by a jsx element <...>. This jsx element will have the function binding as wanted to your component. I found a similar solution here: Replace part of string with tag in JSX

Upvotes: 1

Thanigainathan
Thanigainathan

Reputation: 1547

You can set the bind key word at the end like below instead of the example you have given.

onInput=this.handleInput(id).bind(this)

or just call this method here and bind it at the constructor level.

onInput=this.handleInput(id)

constructor() {
   super();
   this.handleInput=this.handleInput.bind(this);
 }

Upvotes: 0

Damien Leroux
Damien Leroux

Reputation: 11693

There is a proper way to render a string with react:

Use dangerouslySetInnerHTML to inject HTML as a string in React. Subject is treated here

Regards

Upvotes: 0

Related Questions