【问题标题】:how to access vairables outside of map function in js and jsx in a React component如何在 React 组件中访问 js 和 jsx 中的 map 函数之外的变量
【发布时间】:2015-06-26 20:52:46
【问题描述】:
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 会更好吗?难住了,请停下来!

【问题讨论】:

    标签: javascript reactjs react-jsx


    【解决方案1】:

    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" 或非常模糊的内容。

    【讨论】:

    • 非常感谢。我对 JS 和前端的东西比较陌生,但我会研究这个。谢谢!
    • 我得到了你不知道的 JS:this & Object Prototype,我已经完成了一半——真的需要那个。这也是唯一开箱即用的解决方案,而且非常简单。 +1 谢谢!
    【解决方案2】:

    编辑 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 作为第二个参数传递来将正确的this 绑定到map 回调

    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

    【讨论】:

    • 谢谢。嗯,我有点跟随,但不是一路,你能详细说明吗?
    • 构建组件的有趣方式,感谢分享。我仍然不确定我是否理解 this.props 将如何在 map 函数中可用 - 但我需要更深入地研究 javascript,因为它不是我的主要语言。我可以剪切/粘贴您的示例以使我的代码工作吗?谢谢
    • 感谢您提供包含链接的深思熟虑的答案,非常感谢!
    【解决方案3】:

    您是否使用了转译器——比如 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 that = this;
        var pieces = that.props.pieces.map( function(piece, i) {
        return (
          <Piece pieceData={piece} onDeletePiece3={that.props.onDeletePiece2} key={i}/>
        )
      })
    

    ...

    【讨论】:

      猜你喜欢
      • 2021-10-04
      • 2014-07-11
      • 2022-01-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2021-07-15
      • 1970-01-01
      • 2020-10-17
      相关资源
      最近更新 更多