javascript 如何在 React 组件中访问 js 和 jsx 中的 map 函数之外的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31081970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 13:15:03  来源:igfitidea点击:

how to access vairables outside of map function in js and jsx in a React component

javascriptreactjsreact-jsx

提问by bignore59

var PieceList = React.createClass({

  render: function() {

    var pieces;
    if (this.props.pieces && this.props.onDeletePiece2) {
      var pieces = this.props.pieces.map(function (piece) {
        return (
          <Piece pieceData={piece} onDeletePiece3={this.props.onDeletePiece2} />
        )
      });
    }
    return (
      <div className="piecesTable">
        {pieces}
      </div>
    );  
  }
});

I'm stumped as to how to get this to work. The problem is that {this.props} is not available inside of the map function.

我很难过如何让它发挥作用。问题是 {this.props} 在 map 函数内部不可用。

Would a foreach be better here? stumped, pls halp!

在这里使用 foreach 会更好吗?难住了,请停下来!

回答by Josh Beam

mapis just a regular JavaScript method (see Array.prototype.map). It can take an argument that sets the context (.map(callback[, thisArg])):

map只是一个常规的 JavaScript 方法(参见Array.prototype.map)。它可以采用设置上下文的参数 ( .map(callback[, thisArg])):

var PieceList = React.createClass({

  render: function() {

    var pieces;
    if (this.props.pieces && this.props.onDeletePiece2) {
      var pieces = this.props.pieces.map(function (piece) {
        return (
          <Piece pieceData={piece} onDeletePiece3={this.props.onDeletePiece2} />
        )
      }, this); // need to add the context
    }
    return (
      <div className="piecesTable">
        {pieces}
      </div>
    );  
  }
});

I would suggest going back and reading about thisin JavaScript. When you pass an anonymous function to most methods (like .map, .forEach, etc.), it takes the global context (which is almost always window). If you pass in thisas the last argument, since that thisis referring to the class you just created with React.createClass, it'll set the correct context.

我建议返回并阅读thisJavaScript。当您将匿名函数传递给大多数方法(如.map.forEach等)时,它采用全局上下文(几乎总是window)。如果你this作为最后一个参数传入,因为它this指的是你刚刚创建的类React.createClass,它会设置正确的上下文。

In other words, the way you were trying to do it was access window.props, which obviously doesn't exist. I'd if you opened your console to debug, you'd see the error Object Window doesn't have the property "props"or something very obfuscated.

换句话说,您尝试这样做的方式是 access window.props,这显然不存在。如果您打开控制台进行调试,您会看到错误Object Window doesn't have the property "props"或非常模糊的内容。

回答by Thank you

EDIT 2: React 0.14.x

编辑 2:反应 0.14.x

You can now define stateless functional componentsfor components that do not require complex lifecycle event hooks or internal state

您现在可以为不需要复杂生命周期事件挂钩或内部状态的组件定义无状态功能组件

const PieceList = ({pieces, onDeletePiece2}) => {
  if (!onDeletePiece2) return;
  return (
    <div className="piecesTable">
      {pieces.map(x => (
        <Pieces pieceData={x} onDeletePiece3={onDeletePiece2}>
      ))}
    </div>
  );
};


EDIT 1: ES6

编辑 1:ES6

As ES6 continues to become more prominent, you can also avoid nitpicky context issues by using an ES6 arrow function.

随着 ES6 继续变得更加突出,您还可以通过使用 ES6箭头函数来避免挑剔的上下文问题。

class PieceList extends React.Component {
  renderPiece(piece) {
    return <Piece pieceData={piece} onDeletePiece3={this.props.onDeletePiece2} />;
  }
  render() {
    if (!this.props.onDeletePiece2) return;
    return (
      <div className="piecesTable">
        {this.props.pieces.map(piece => this.renderPiece(piece))}
      <div>
    );
  }
}

To get this to run in most environments, you'd need to "transpile" it using something like babel.js

为了让它在大多数环境中运行,你需要使用类似babel.js 的东西“转换”它



The quick answer is that you need to bind the proper thisto the mapcallback by passing thisas the second arg

快速回答是您需要通过作为第二个参数传递来将正确的绑定thismap回调this

this.props.pieces.map(..., this);

This might be a better way to write your component tho

这可能是编写组件的更好方法

var PieceList = React.createClass({

  renderPiece: function(piece) {
    return <Piece pieceData={piece} onDeletePiece3={this.props.onDeletePiece2} />;
  },

  render: function() {
    if (!this.props.onDeletePiece2) return;
    return (
      <div className="piecesTable">
        {this.props.pieces.map(this.renderPiece, this)}
      </div>
    );
  }
});

Regarding your comment about map

关于你的评论 map

var x = {a: 1, b: 2};

['a', 'b'].map(function(key) {
  // `this` is set to `x`
  // `key` will be `'a'` for the first iteration
  // `key` will be `'b'` for the second iteration
  console.log(this[key]);
}, x); // notice we're passing `x` as the second argument to `map`

Will output

会输出

// "1"
// "2"

Notice how the second argument to mapcan set the context for the function. When you call thisinside the function, it will be equal to the second variable that was sent to map.

注意第二个参数 tomap如何设置函数的上下文。当您this在函数内部调用时,它将等于发送到的第二个变量map

This is JavaScript basics and you should definitely read up more here

这是 JavaScript 基础知识,你绝对应该在这里阅读更多

回答by Hal Helms

Are you using a transpiler -- something like Babel? If so, this code will work fine:

你在使用转译器——比如 Babel 吗?如果是这样,此代码将正常工作:

if (this.props.pieces && this.props.onDeletePiece2) {
  var pieces = this.props.pieces.map((piece, i) => {
    return (
      <Piece pieceData={piece} onDeletePiece3={this.props.onDeletePiece2} key={i}/>
    )
  });
  ...
if (this.props.pieces && this.props.onDeletePiece2) {
  var pieces = this.props.pieces.map((piece, i) => {
    return (
      <Piece pieceData={piece} onDeletePiece3={this.props.onDeletePiece2} key={i}/>
    )
  });
  ...

If you can't use a transpiler, you could do this:

如果你不能使用转译器,你可以这样做:

if (this.props.pieces && this.props.onDeletePiece2) {  
var that = this;
    var pieces = that.props.pieces.map( function(piece, i) {
    return (
      <Piece pieceData={piece} onDeletePiece3={that.props.onDeletePiece2} key={i}/>
    )
  })
if (this.props.pieces && this.props.onDeletePiece2) {  
var that = this;
    var pieces = that.props.pieces.map( function(piece, i) {
    return (
      <Piece pieceData={piece} onDeletePiece3={that.props.onDeletePiece2} key={i}/>
    )
  })

...

...