简体   繁体   中英

JSX binding this to a function within a map

I am using a map function and have tested and confirmed that within the maps function this is referencing the class object as desired.

When I try passing this again by binding it to a jsx function, it doesn't pass this as desired.

Error: Uncaught TypeError: _this3.checkType(...).bind is not a function

// wrapped in a class

checkType(type, options, placeholder, name, handleUpdatedValue, defvalue, index) {

        console.log(this);

        switch(type) {
            case 'select':
                return <select onChange={handleUpdatedValue.bind(this)} >{options.map((option, i) => <option value={option} key={i}>{option}</option>)}</select>
                break;
            case 'text':
                return <input onChange={handleUpdatedValue.bind(this)} name={name} placeholder={placeholder} type="text" />
                break;
            case 'date':
                return <input onChange={handleUpdatedValue.bind(this)} name={name} placeholder={placeholder} type="date" />
                break;
            default: 
                console.log('Error: Invalid Type');
        }
        return type === 'select' ? <select></select> : <input />
    }

return(
        <div className="formwrapper thinshadow">    
            <h3>{this.props.header}</h3>
            {this.getFields().map((field, i) => {
                <div key={i} className={field.classes}>
                    {this.checkType(field.type, field.options, field.placeholder, field.name, this.handleUpdatedValue.bind(this), field.defvalue, field.index).bind(this)}

                                                                  // DOES NOT WORK ^

                    <div className="minilabel"></div>
                </div>
            }, this)}                                         // THIS WORKS

            <button className="btn btn-primary" 
                    onClick={() => this.props.onClick(values)} >
                    Save
            </button>
        </div>  
    );

You are invoking the function instead of binding it.

this.checkType(field.type, field.options, field.placeholder, field.name, this.handleUpdatedValue.bind(this), field.defvalue, field.index).bind(this)

should be

this.checkType.bind(this, field.type, field.options, field.placeholder, field.name, this.handleUpdatedValue.bind(this), field.defvalue, field.index)

bind Usage

fun.bind(thisArg[, arg1[, arg2[, ...]]]

Refer to this link for more details:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Edit

You use bind when you are passing your function to another context (another this pretty much), and still want the function to be invoked under the original this .

In your situation, you don't need to bind because within your map , you have the same this . See You Don't Need to Bind This in React when using forEach and map .

But if you do want to, I strongly advise against bind ing when you are iterating. You can use closure, and bind before the iteration.

bind is slow , even though it doesn't really matter most of the time. But more importantly, you don't want to bind in iterations like forEach or map because it's easy to lose the context ( this ) without knowing (when you are not using React). And you will scratch you head for a few hours.

If you are using React, you can bind in the render function.

render: () {
  const checkType = this.checkType.bind(this);
  render (
    map((node) => { checkType(...) });
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM