【问题标题】:Use es6 classes other than component (React Js)使用组件以外的 es6 类(React Js)
【发布时间】:2017-07-22 19:15:49
【问题描述】:

在React的官方tutorial(井字游戏)中,使用了三个组件:GameBoardSquare

Game 包含一个 squares 数组,可以包含 X、O 和 null:这三个都是原始类型。

我的问题:使用 es6 类(不扩展组件,因为不渲染任何东西)来保存信息原语肯定不能保存,这是一种公认的做法吗?这些类也可以从其他类继承。

例如,我们可以将Piece 类的对象存储在squares 数组中,而不是X/O 显示piece.name 在正方形中吗?我们可以将piecei 移动到j 以反映在棋盘上吗?

需要问这个有两个原因:

  1. 几乎所有 React 示例都围绕组件展开。我还没有看到其他使用的类。

  2. 不鼓励对组件 (composition vs inheritance) 进行继承,我认为在上面的示例中需要专门化 Piece 类。

谢谢。

【问题讨论】:

  • 我想不出你不能这样做的原因,但我能想到你不应该这样做的原因。您正在尝试做的事情我相信使用功能性无状态组件来表示Piece 会更好地完成。 Piece 的属性将由父组件的状态或redux 存储提供给它。 Piece 本身只是展示性的。它所在位置的逻辑应该在更高的组件中。我真的不认为这里需要上课。
  • 这个问题可能是主观的,可能无法回答。以我的经验,通常对象用于状态{age: 25, name: 'John Doe'},类不用于状态,而是用于组件,如您所说。请参阅state & lifecycle docs。
  • @styfle,同意对象可以包含状态但不涉及继承。 Person 可以有{age: 25, name: 'John Doe'},但它的扩展类Employee 应该有相同的字段加上其他一些字段。那是从面向对象的角度来看的。只是想知道我们将如何在 React 中解决这个问题。还是谢谢。
  • 谢谢@KyleRichardson。 “Piece 的属性将由父组件的状态赋予它”。这就是我的困惑所在。这些属性存储在哪里以及如何存储?对象,类,还是别的?绝对不是组件(函数式或类),因为没有渲染任何内容,这就是组件的用途。
  • @TalhaAwan 他们的状态,如果他们需要与他们直接相关的状态,将被存储在父组件状态的对象中,或者在store中。他们甚至可能不需要状态,具体取决于您想要做什么并且可能不需要。他们可能会得到道具。他们的位置将由董事会的状态决定。他们的名字、长相等将由他们创建的道具决定。

标签: javascript reactjs inheritance ecmascript-6


【解决方案1】:

这是我所说的一个例子。我没有包含任何状态更新机制,这是相当概念性的,但我想你会明白要点的。

// holds the state of your board and calculates the view layer
class Board extends PureComponent {
    constructor( props ) {
        super( props );

        // create pieces for however you want the game to start
        this.pieces = {
            p1: new piece( "Lumberjack" ),
            p2: new piece( "Lumberjack" ),
            p3: new piece( "Lumberjack" ),
            p4: new piece( "Tree" ),
            p5: new piece( "Tree" ),
            p6: new piece( "Tree" )
        }

        // flatten for easy and speed of access
        const { p1, p2, p3, p4, p5, p6 } = this.pieces;

        // initial state, this is what gets updated by this.setState method
        // to update the rendered view
        this.state ={
            squares: [
                [ p1, p2, p3 ],
                [ null, null, null ],
                [ p4, p5, p6 ]
            ]
        };
    }

    // render method that produces the view
    render() {
        const { squares } = this.state;
        const iLength = squares.length;
        let i, j jLength, components = [ ];

        // generate the Squares from this.state data
        for ( i = 0; i < iLength; i++ ) {
            jLength = squares[ i ].length;
            for ( j = 0; jLength; j++ ) {
                components.push( <Square piece={ squares[ i ][ j ] } /> );
            }
        }

        // render the Squares containing the pieces
        return (
            <div className="board">
                { components }
            </div>
        );
    }
}

// piece constructor
function piece( name ) {
    this.name = name;
}

你最终会在一个板上有 9 个方格。一边是伐木工人,中间是空旷的,另一边是非常害怕的树。

【讨论】:

  • 你使用了片段构造函数,为什么不用类?假设我们也想移动棋盘上的棋子。 Lumberjacks 和 Tree 的移动方式不同,但两者都不能离开棋盘。这就是我想到具有move() 方法的Piece 类的地方。 LumberjackTree 继承自 Piece。如果我们move() Lumberjack,它会调用 super.move() 来确认它不会离开桌子,然后检查它自己的逻辑,如果允许,最后会移动。有这种效果。感谢你的回答。真的很感激!
  • 你可以在你的棋盘上放一个 move 方法,它接受参数并将参数存储在棋子上,就像现在一样。对我来说似乎是一个更简单的解决方案。
  • 是的move() 将在BoardisMoveLegal(src, dest)Piece。我认为仍然需要Piece 的课程。为什么不使用带有方法的类是我没有得到的:) 因为构造函数本质上是在做同样的事情。感谢您的时间和回答。接受它。
  • isMoveLegal 方法也可以在板上。您从游戏中处于board 状态的棋子位置获取src,而dest 将由move 方法中棋子提供的参数计算。 isMoveLegalmove 内部被调用,如果它不合法,它返回 false 或调用自身来计算另一个移动。只是一个想法。
猜你喜欢
  • 2021-08-11
  • 2016-10-15
  • 2019-11-27
  • 2017-12-13
  • 2016-02-05
  • 2015-11-20
相关资源
最近更新 更多