最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to trigger 'this' within a loop in React - Stack Overflow

programmeradmin1浏览0评论

I am kind-of new to react and having trouble getting value of a radio button generated from a loop. I have a fiddle set-up at: /.

The example has two type of radio buttons. One group is generated using loop and the other one without loop. The one without loop works (logs the value of the button) but the ones created with the loop doesn't work when I try to console log the value of the radio button.

Thank you in advance.

var Inputs = React.createClass({

    getInitialState: function(){
        return {
            radios: {
                a: { radio: 'Radio Loop A' },
                b: { radio: 'Radio Loop B' },
                c: { radio: 'Radio Loop C' }
            },

            radioNoLoop: 'Radio No Loop' 
        }
    },

    selectHandlerLoop: function(e){
        console.log(e.target.value);
    },

    selectHandle: function(e){
        console.log(e.target.value);
    },

    render: function() {
        var radios = this.state.radios;
        var r = this;
        return(
            <div>
                {/* Creating radio buttons using Array */}
                {Object.keys(radios).map(function(key,r) {
                    return ( 
                        <div key={key}>
                            <label forHTML={key}>
                                <input type="radio" name="loopTest" value={radios[key].radio} id={key} nChange={r.selectHandlerLoop} /> {radios[key].radio}
                            </label>
                        </div>

                    );
                })}

               <hr />
               {/* Radio button no array loop */}
               <label forHTML="noLoop">
                   <input type="radio" id="noLoop" value="noLoop" onChange={this.selectHandle}/> {this.state.radioNoLoop}
               </label>
            </div>
        );
    }
});

React.render(<Inputs />, document.getElementById('container'));

I am kind-of new to react and having trouble getting value of a radio button generated from a loop. I have a fiddle set-up at: https://jsfiddle/rexonms/zrax0zfa/.

The example has two type of radio buttons. One group is generated using loop and the other one without loop. The one without loop works (logs the value of the button) but the ones created with the loop doesn't work when I try to console log the value of the radio button.

Thank you in advance.

var Inputs = React.createClass({

    getInitialState: function(){
        return {
            radios: {
                a: { radio: 'Radio Loop A' },
                b: { radio: 'Radio Loop B' },
                c: { radio: 'Radio Loop C' }
            },

            radioNoLoop: 'Radio No Loop' 
        }
    },

    selectHandlerLoop: function(e){
        console.log(e.target.value);
    },

    selectHandle: function(e){
        console.log(e.target.value);
    },

    render: function() {
        var radios = this.state.radios;
        var r = this;
        return(
            <div>
                {/* Creating radio buttons using Array */}
                {Object.keys(radios).map(function(key,r) {
                    return ( 
                        <div key={key}>
                            <label forHTML={key}>
                                <input type="radio" name="loopTest" value={radios[key].radio} id={key} nChange={r.selectHandlerLoop} /> {radios[key].radio}
                            </label>
                        </div>

                    );
                })}

               <hr />
               {/* Radio button no array loop */}
               <label forHTML="noLoop">
                   <input type="radio" id="noLoop" value="noLoop" onChange={this.selectHandle}/> {this.state.radioNoLoop}
               </label>
            </div>
        );
    }
});

React.render(<Inputs />, document.getElementById('container'));
Share Improve this question edited May 22, 2015 at 20:12 Jonny Buchanan 62.8k17 gold badges145 silver badges150 bronze badges asked May 22, 2015 at 16:39 rexrex 1,0235 gold badges30 silver badges48 bronze badges 1
  • What exactly is not working? Please explain the issue. – Felix Kling Commented May 22, 2015 at 16:43
Add a ment  | 

2 Answers 2

Reset to default 7

javascript map actually has functionality for what you're trying to do. you pass this to the second argument of map (after the callback):

{Object.keys(radios).map(function(key) {
  return ( 
    <div key={key}>
      <label forHTML={key}>
        <input type="radio" name="loopTest" value={radios[key].radio} id={key} onChange={this.selectHandlerLoop} /> {radios[key].radio}
      </label>
    </div>
  );
}, this)}

Your problem has nothing to do with React. You seem to have a misunderstanding of how functions / closures work.

Lets look at that part:

Object.keys(radios).map(function(key,r) { ... });

This declares a function expecting two arguments, key and r, and passes it to .map. .map will call the function and provide the corresponding arguments.

If you look at the .map documentation you can see that .map passes three arguments to the callback:

callback

Function that produces an element of the new Array, taking three arguments:

  • currentValue: The current element being processed in the array.
  • index: The index of the current element being processed in the array.
  • array: The array map was called upon.

So what will the value of r be? It will be the index of the current element.

The parameter r has nothing to do with the variable r you declared with

var r = this;

If you want r inside the callback to refer to that variable, remove it from the parameter list

Object.keys(radios).map(function(key) { ... });
//                                  ^ no r

r is now a free variable inside the callback and will be looked up in higher scopes.

To learn more about closures, have a look at this MDN article.


We can simplify the mapping by using ES6 arrow functions, which you can use if you transpile your code with Babel or jsx --harmony:

{Object.keys(radios).map(key => 
  <div key={key}>
    <label forHTML={key}>
      <input ... nChange={this.selectHandlerLoop} /> {radios[key].radio}
    </label>
  </div>
)}

Because this inside arrow functions is lexically scoped, it will refer to the this value of the render method, which is your React ponent.

发布评论

评论列表(0)

  1. 暂无评论