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

时间:2015-06-26 20:52:46

标签: javascript reactjs react-jsx

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>
    );  
  }
});

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

这里的foreach会更好吗?难倒,请停下来!

3 个答案:

答案 0 :(得分:15)

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>
    );  
  }
});

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

换句话说,您尝试这样做的方式是访问window.props,这显然不存在。如果你打开控制台进行调试,你会看到错误Object Window doesn't have the property "props"或者非常混淆的东西。

答案 1 :(得分:5)

编辑2:反应0.14.x

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

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

编辑1:ES6

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

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>
    );
  }
}

要在大多数环境中运行此功能,您需要使用类似babel.js

的内容来“转换”它

快速回答是,您需要通过将this作为第二个arg

来将正确的map绑定到this回调。
this.props.pieces.map(..., this);

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

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>
    );
  }
});

关于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`

将输出

// "1"
// "2"

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

这是JavaScript基础知识,您绝对应该阅读更多here

答案 2 :(得分:0)

您使用的是转换器吗 - 像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 (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}/>
    )
  })