diff --git a/src/screens/Game/GameScreen.js b/src/screens/Game/GameScreen.js index f30806a..df14eba 100644 --- a/src/screens/Game/GameScreen.js +++ b/src/screens/Game/GameScreen.js @@ -5,17 +5,21 @@ import {Alert, View} from 'react-native'; import {IconButton, Text, withTheme} from 'react-native-paper'; import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons"; import GameLogic from "./GameLogic"; -import Grid from "./components/Grid"; +import type {Grid} from "./components/GridComponent"; +import GridComponent from "./components/GridComponent"; import Preview from "./components/Preview"; import i18n from "i18n-js"; import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton"; +import {StackNavigationProp} from "@react-navigation/stack"; +import type {CustomTheme} from "../../managers/ThemeManager"; type Props = { - navigation: Object, + navigation: StackNavigationProp, + theme: CustomTheme, } type State = { - grid: Array>, + grid: Grid, gameRunning: boolean, gameTime: number, gameScore: number, @@ -24,19 +28,11 @@ type State = { class GameScreen extends React.Component { - colors: Object; - logic: GameLogic; - onTick: Function; - onClock: Function; - onGameEnd: Function; - updateGrid: Function; - updateGridScore: Function; constructor(props) { super(props); - this.colors = props.theme.colors; - this.logic = new GameLogic(20, 10, this.colors); + this.logic = new GameLogic(20, 10, this.props.theme.colors); this.state = { grid: this.logic.getCurrentGrid(), gameRunning: false, @@ -44,38 +40,32 @@ class GameScreen extends React.Component { gameScore: 0, gameLevel: 0, }; - this.onTick = this.onTick.bind(this); - this.onClock = this.onClock.bind(this); - this.onGameEnd = this.onGameEnd.bind(this); - this.updateGrid = this.updateGrid.bind(this); - this.updateGridScore = this.updateGridScore.bind(this); - this.props.navigation.addListener('blur', this.onScreenBlur.bind(this)); - this.props.navigation.addListener('focus', this.onScreenFocus.bind(this)); + this.props.navigation.addListener('blur', this.onScreenBlur); + this.props.navigation.addListener('focus', this.onScreenFocus); } componentDidMount() { - const rightButton = this.getRightButton.bind(this); this.props.navigation.setOptions({ - headerRight: rightButton, + headerRight: this.getRightButton, }); this.startGame(); } - getRightButton() { + getRightButton = () => { return - this.togglePause()}/> + ; } /** * Remove any interval on un-focus */ - onScreenBlur() { + onScreenBlur = () => { if (!this.logic.isGamePaused()) this.logic.togglePause(); } - onScreenFocus() { + onScreenFocus = () => { if (!this.logic.isGameRunning()) this.startGame(); else if (this.logic.isGamePaused()) @@ -97,7 +87,7 @@ class GameScreen extends React.Component { return format; } - onTick(score: number, level: number, newGrid: Array>) { + onTick = (score: number, level: number, newGrid: Grid) => { this.setState({ gameScore: score, gameLevel: level, @@ -105,50 +95,50 @@ class GameScreen extends React.Component { }); } - onClock(time: number) { + onClock = (time: number) => { this.setState({ gameTime: time, }); } - updateGrid(newGrid: Array>) { + updateGrid = (newGrid: Grid) => { this.setState({ grid: newGrid, }); } - updateGridScore(newGrid: Array>, score: number) { + updateGridScore = (newGrid: Grid, score: number) => { this.setState({ grid: newGrid, gameScore: score, }); } - togglePause() { + togglePause = () => { this.logic.togglePause(); if (this.logic.isGamePaused()) this.showPausePopup(); } - showPausePopup() { + showPausePopup = () => { Alert.alert( i18n.t("screens.game.pause"), i18n.t("screens.game.pauseMessage"), [ - {text: i18n.t("screens.game.restart.text"), onPress: () => this.showRestartConfirm()}, - {text: i18n.t("screens.game.resume"), onPress: () => this.togglePause()}, + {text: i18n.t("screens.game.restart.text"), onPress: this.showRestartConfirm}, + {text: i18n.t("screens.game.resume"), onPress: this.togglePause}, ], {cancelable: false}, ); } - showRestartConfirm() { + showRestartConfirm = () => { Alert.alert( i18n.t("screens.game.restart.confirm"), i18n.t("screens.game.restart.confirmMessage"), [ - {text: i18n.t("screens.game.restart.confirmNo"), onPress: () => this.showPausePopup()}, - {text: i18n.t("screens.game.restart.confirmYes"), onPress: () => this.startGame()}, + {text: i18n.t("screens.game.restart.confirmNo"), onPress: this.showPausePopup}, + {text: i18n.t("screens.game.restart.confirmYes"), onPress: this.startGame}, ], {cancelable: false}, ); @@ -163,20 +153,20 @@ class GameScreen extends React.Component { message, [ {text: i18n.t("screens.game.gameOver.exit"), onPress: () => this.props.navigation.goBack()}, - {text: i18n.t("screens.game.restart.text"), onPress: () => this.startGame()}, + {text: i18n.t("screens.game.restart.text"), onPress: this.startGame}, ], {cancelable: false}, ); } - startGame() { + startGame = () => { this.logic.startGame(this.onTick, this.onClock, this.onGameEnd); this.setState({ gameRunning: true, }); } - onGameEnd(time: number, score: number, isRestart: boolean) { + onGameEnd = (time: number, score: number, isRestart: boolean) => { this.setState({ gameTime: time, gameScore: score, @@ -187,6 +177,7 @@ class GameScreen extends React.Component { } render() { + const colors = this.props.theme.colors; return ( { }}> {this.getFormattedTime(this.state.gameTime)} { }}> { }}> {this.state.gameScore} - { right: 5, }}> { onPressIn={() => this.logic.downPressedIn(this.updateGridScore)} onPress={() => this.logic.pressedOut()} style={{marginLeft: 'auto'}} - color={this.colors.tetrisScore} + color={colors.tetrisScore} /> diff --git a/src/screens/Game/GridManager.js b/src/screens/Game/GridManager.js index f08ca26..9e19e96 100644 --- a/src/screens/Game/GridManager.js +++ b/src/screens/Game/GridManager.js @@ -2,39 +2,37 @@ import Piece from "./Piece"; import ScoreManager from "./ScoreManager"; -import type {coordinates} from './Shapes/BaseShape'; - - -export type cell = {color: string, isEmpty: boolean, key: string}; -export type grid = Array>; +import type {Coordinates} from './Shapes/BaseShape'; +import type {Grid} from "./components/GridComponent"; +import type {Cell} from "./components/CellComponent"; +import type {CustomTheme} from "../../managers/ThemeManager"; /** * Class used to manage the game grid - * */ export default class GridManager { - #currentGrid: grid; - #colors: Object; + #currentGrid: Grid; + #theme: CustomTheme; /** * Initializes a grid of the given size * * @param width The grid width * @param height The grid height - * @param colors Object containing current theme colors + * @param theme Object containing current theme */ - constructor(width: number, height: number, colors: Object) { - this.#colors = colors; + constructor(width: number, height: number, theme: CustomTheme) { + this.#theme = theme; this.#currentGrid = this.getEmptyGrid(height, width); } /** * Get the current grid * - * @return {grid} The current grid + * @return {Grid} The current grid */ - getCurrentGrid(): grid { + getCurrentGrid(): Grid { return this.#currentGrid; } @@ -42,13 +40,13 @@ export default class GridManager { * Get a new empty grid line of the given size * * @param width The line size - * @return {Array} + * @return {Array} */ - getEmptyLine(width: number): Array { + getEmptyLine(width: number): Array { let line = []; for (let col = 0; col < width; col++) { line.push({ - color: this.#colors.tetrisBackground, + color: this.#theme.colors.tetrisBackground, isEmpty: true, key: col.toString(), }); @@ -61,9 +59,9 @@ export default class GridManager { * * @param width The grid width * @param height The grid height - * @return {grid} A new empty grid + * @return {Grid} A new empty grid */ - getEmptyGrid(height: number, width: number): grid { + getEmptyGrid(height: number, width: number): Grid { let grid = []; for (let row = 0; row < height; row++) { grid.push(this.getEmptyLine(width)); @@ -91,21 +89,21 @@ export default class GridManager { * Gets the lines to clear around the given piece's coordinates. * The piece's coordinates are used for optimization and to prevent checking the whole grid. * - * @param coord The piece's coordinates to check lines at + * @param pos The piece's coordinates to check lines at * @return {Array} An array containing the line numbers to clear */ - getLinesToClear(coord: Array): Array { + getLinesToClear(pos: Array): Array { let rows = []; - for (let i = 0; i < coord.length; i++) { + for (let i = 0; i < pos.length; i++) { let isLineFull = true; - for (let col = 0; col < this.#currentGrid[coord[i].y].length; col++) { - if (this.#currentGrid[coord[i].y][col].isEmpty) { + for (let col = 0; col < this.#currentGrid[pos[i].y].length; col++) { + if (this.#currentGrid[pos[i].y][col].isEmpty) { isLineFull = false; break; } } - if (isLineFull && rows.indexOf(coord[i].y) === -1) - rows.push(coord[i].y); + if (isLineFull && rows.indexOf(pos[i].y) === -1) + rows.push(pos[i].y); } return rows; } diff --git a/src/screens/Game/Piece.js b/src/screens/Game/Piece.js index 5293de9..daece82 100644 --- a/src/screens/Game/Piece.js +++ b/src/screens/Game/Piece.js @@ -5,8 +5,10 @@ import ShapeO from "./Shapes/ShapeO"; import ShapeS from "./Shapes/ShapeS"; import ShapeT from "./Shapes/ShapeT"; import ShapeZ from "./Shapes/ShapeZ"; -import type {coordinates} from './Shapes/BaseShape'; -import type {grid} from './GridManager'; +import type {Coordinates} from './Shapes/BaseShape'; +import BaseShape from "./Shapes/BaseShape"; +import type {Grid} from "./components/GridComponent"; +import type {CustomTheme} from "../../managers/ThemeManager"; /** * Class used as an abstraction layer for shapes. @@ -24,26 +26,26 @@ export default class Piece { ShapeT, ShapeZ, ]; - #currentShape: Object; - #colors: Object; + #currentShape: BaseShape; + #theme: CustomTheme; /** * Initializes this piece's color and shape * - * @param colors Object containing current theme colors + * @param theme Object containing current theme */ - constructor(colors: Object) { - this.#currentShape = this.getRandomShape(colors); - this.#colors = colors; + constructor(theme: CustomTheme) { + this.#currentShape = this.getRandomShape(theme); + this.#theme = theme; } /** * Gets a random shape object * - * @param colors Object containing current theme colors + * @param theme Object containing current theme */ - getRandomShape(colors: Object) { - return new this.#shapes[Math.floor(Math.random() * 7)](colors); + getRandomShape(theme: CustomTheme) { + return new this.#shapes[Math.floor(Math.random() * 7)](theme); } /** @@ -51,13 +53,13 @@ export default class Piece { * * @param grid The grid to remove the piece from */ - removeFromGrid(grid: grid) { - const coord: Array = this.#currentShape.getCellsCoordinates(true); - for (let i = 0; i < coord.length; i++) { - grid[coord[i].y][coord[i].x] = { - color: this.#colors.tetrisBackground, + removeFromGrid(grid: Grid) { + const pos: Array = this.#currentShape.getCellsCoordinates(true); + for (let i = 0; i < pos.length; i++) { + grid[pos[i].y][pos[i].x] = { + color: this.#theme.colors.tetrisBackground, isEmpty: true, - key: grid[coord[i].y][coord[i].x].key + key: grid[pos[i].y][pos[i].x].key }; } } @@ -68,13 +70,13 @@ export default class Piece { * @param grid The grid to add the piece to * @param isPreview Should we use this piece's current position to determine the cells? */ - toGrid(grid: grid, isPreview: boolean) { - const coord: Array = this.#currentShape.getCellsCoordinates(!isPreview); - for (let i = 0; i < coord.length; i++) { - grid[coord[i].y][coord[i].x] = { + toGrid(grid: Grid, isPreview: boolean) { + const pos: Array = this.#currentShape.getCellsCoordinates(!isPreview); + for (let i = 0; i < pos.length; i++) { + grid[pos[i].y][pos[i].x] = { color: this.#currentShape.getColor(), isEmpty: false, - key: grid[coord[i].y][coord[i].x].key + key: grid[pos[i].y][pos[i].x].key }; } } @@ -87,15 +89,15 @@ export default class Piece { * @param height The grid's height * @return {boolean} If the position is valid */ - isPositionValid(grid: grid, width: number, height: number) { + isPositionValid(grid: Grid, width: number, height: number) { let isValid = true; - const coord: Array = this.#currentShape.getCellsCoordinates(true); - for (let i = 0; i < coord.length; i++) { - if (coord[i].x >= width - || coord[i].x < 0 - || coord[i].y >= height - || coord[i].y < 0 - || !grid[coord[i].y][coord[i].x].isEmpty) { + const pos: Array = this.#currentShape.getCellsCoordinates(true); + for (let i = 0; i < pos.length; i++) { + if (pos[i].x >= width + || pos[i].x < 0 + || pos[i].y >= height + || pos[i].y < 0 + || !grid[pos[i].y][pos[i].x].isEmpty) { isValid = false; break; } @@ -114,7 +116,7 @@ export default class Piece { * @param freezeCallback Callback to use if the piece should freeze itself * @return {boolean} True if the move was valid, false otherwise */ - tryMove(x: number, y: number, grid: grid, width: number, height: number, freezeCallback: Function) { + tryMove(x: number, y: number, grid: Grid, width: number, height: number, freezeCallback: () => void) { if (x > 1) x = 1; // Prevent moving from more than one tile if (x < -1) x = -1; if (y > 1) y = 1; @@ -143,7 +145,7 @@ export default class Piece { * @param height The grid's height * @return {boolean} True if the rotation was valid, false otherwise */ - tryRotate(grid: grid, width: number, height: number) { + tryRotate(grid: Grid, width: number, height: number) { this.removeFromGrid(grid); this.#currentShape.rotate(true); if (!this.isPositionValid(grid, width, height)) { @@ -158,9 +160,9 @@ export default class Piece { /** * Gets this piece used cells coordinates * - * @return {Array} An array of coordinates + * @return {Array} An array of coordinates */ - getCoordinates(): Array { + getCoordinates(): Array { return this.#currentShape.getCellsCoordinates(true); } } diff --git a/src/screens/Game/Shapes/BaseShape.js b/src/screens/Game/Shapes/BaseShape.js index e1890ac..82b72ab 100644 --- a/src/screens/Game/Shapes/BaseShape.js +++ b/src/screens/Game/Shapes/BaseShape.js @@ -1,10 +1,14 @@ // @flow -export type coordinates = { +import type {CustomTheme} from "../../../managers/ThemeManager"; + +export type Coordinates = { x: number, y: number, } +type Shape = Array>; + /** * Abstract class used to represent a BaseShape. * Abstract classes do not exist by default in Javascript: we force it by throwing errors in the constructor @@ -12,16 +16,18 @@ export type coordinates = { */ export default class BaseShape { - #currentShape: Array>; + #currentShape: Shape; #rotation: number; - position: coordinates; + position: Coordinates; + theme: CustomTheme; /** * Prevent instantiation if classname is BaseShape to force class to be abstract */ - constructor() { + constructor(theme: CustomTheme) { if (this.constructor === BaseShape) throw new Error("Abstract class can't be instantiated"); + this.theme = theme; this.#rotation = 0; this.position = {x: 0, y: 0}; this.#currentShape = this.getShapes()[this.#rotation]; @@ -41,7 +47,7 @@ export default class BaseShape { * * Used by tests to read private fields */ - getShapes(): Array>> { + getShapes(): Array { throw new Error("Method 'getShapes()' must be implemented"); } @@ -50,7 +56,7 @@ export default class BaseShape { * * Used by tests to read private fields */ - getCurrentShape(): Array> { + getCurrentShape(): Shape { return this.#currentShape; } @@ -59,9 +65,9 @@ export default class BaseShape { * This will return an array of coordinates representing the positions of the cells used by this object. * * @param isAbsolute Should we take into account the current position of the object? - * @return {Array} This object cells coordinates + * @return {Array} This object cells coordinates */ - getCellsCoordinates(isAbsolute: boolean): Array { + getCellsCoordinates(isAbsolute: boolean): Array { let coordinates = []; for (let row = 0; row < this.#currentShape.length; row++) { for (let col = 0; col < this.#currentShape[row].length; col++) { diff --git a/src/screens/Game/Shapes/ShapeI.js b/src/screens/Game/Shapes/ShapeI.js index d3d2205..5c1141c 100644 --- a/src/screens/Game/Shapes/ShapeI.js +++ b/src/screens/Game/Shapes/ShapeI.js @@ -1,19 +1,17 @@ // @flow import BaseShape from "./BaseShape"; +import type {CustomTheme} from "../../../managers/ThemeManager"; export default class ShapeI extends BaseShape { - #colors: Object; - - constructor(colors: Object) { - super(); + constructor(theme: CustomTheme) { + super(theme); this.position.x = 3; - this.#colors = colors; } getColor(): string { - return this.#colors.tetrisI; + return this.theme.colors.tetrisI; } getShapes() { diff --git a/src/screens/Game/Shapes/ShapeJ.js b/src/screens/Game/Shapes/ShapeJ.js index 391e180..8262088 100644 --- a/src/screens/Game/Shapes/ShapeJ.js +++ b/src/screens/Game/Shapes/ShapeJ.js @@ -1,19 +1,17 @@ // @flow import BaseShape from "./BaseShape"; +import type {CustomTheme} from "../../../managers/ThemeManager"; export default class ShapeJ extends BaseShape { - #colors: Object; - - constructor(colors: Object) { - super(); + constructor(theme: CustomTheme) { + super(theme); this.position.x = 3; - this.#colors = colors; } getColor(): string { - return this.#colors.tetrisJ; + return this.theme.colors.tetrisJ; } getShapes() { diff --git a/src/screens/Game/Shapes/ShapeL.js b/src/screens/Game/Shapes/ShapeL.js index 77562cc..0b65510 100644 --- a/src/screens/Game/Shapes/ShapeL.js +++ b/src/screens/Game/Shapes/ShapeL.js @@ -1,19 +1,17 @@ // @flow import BaseShape from "./BaseShape"; +import type {CustomTheme} from "../../../managers/ThemeManager"; export default class ShapeL extends BaseShape { - #colors: Object; - - constructor(colors: Object) { - super(); + constructor(theme: CustomTheme) { + super(theme); this.position.x = 3; - this.#colors = colors; } getColor(): string { - return this.#colors.tetrisL; + return this.theme.colors.tetrisL; } getShapes() { diff --git a/src/screens/Game/Shapes/ShapeO.js b/src/screens/Game/Shapes/ShapeO.js index e55b3aa..9fec75f 100644 --- a/src/screens/Game/Shapes/ShapeO.js +++ b/src/screens/Game/Shapes/ShapeO.js @@ -1,19 +1,17 @@ // @flow import BaseShape from "./BaseShape"; +import type {CustomTheme} from "../../../managers/ThemeManager"; export default class ShapeO extends BaseShape { - #colors: Object; - - constructor(colors: Object) { - super(); + constructor(theme: CustomTheme) { + super(theme); this.position.x = 4; - this.#colors = colors; } getColor(): string { - return this.#colors.tetrisO; + return this.theme.colors.tetrisO; } getShapes() { diff --git a/src/screens/Game/Shapes/ShapeS.js b/src/screens/Game/Shapes/ShapeS.js index 2124a00..f62c30e 100644 --- a/src/screens/Game/Shapes/ShapeS.js +++ b/src/screens/Game/Shapes/ShapeS.js @@ -1,19 +1,17 @@ // @flow import BaseShape from "./BaseShape"; +import type {CustomTheme} from "../../../managers/ThemeManager"; export default class ShapeS extends BaseShape { - #colors: Object; - - constructor(colors: Object) { - super(); + constructor(theme: CustomTheme) { + super(theme); this.position.x = 3; - this.#colors = colors; } getColor(): string { - return this.#colors.tetrisS; + return this.theme.colors.tetrisS; } getShapes() { diff --git a/src/screens/Game/Shapes/ShapeT.js b/src/screens/Game/Shapes/ShapeT.js index 244bfae..dd01b52 100644 --- a/src/screens/Game/Shapes/ShapeT.js +++ b/src/screens/Game/Shapes/ShapeT.js @@ -1,19 +1,17 @@ // @flow import BaseShape from "./BaseShape"; +import type {CustomTheme} from "../../../managers/ThemeManager"; export default class ShapeT extends BaseShape { - #colors: Object; - - constructor(colors: Object) { - super(); + constructor(theme: CustomTheme) { + super(theme); this.position.x = 3; - this.#colors = colors; } getColor(): string { - return this.#colors.tetrisT; + return this.theme.colors.tetrisT; } getShapes() { diff --git a/src/screens/Game/Shapes/ShapeZ.js b/src/screens/Game/Shapes/ShapeZ.js index 05a619f..f7b8aaa 100644 --- a/src/screens/Game/Shapes/ShapeZ.js +++ b/src/screens/Game/Shapes/ShapeZ.js @@ -1,19 +1,17 @@ // @flow import BaseShape from "./BaseShape"; +import type {CustomTheme} from "../../../managers/ThemeManager"; export default class ShapeZ extends BaseShape { - #colors: Object; - - constructor(colors: Object) { - super(); + constructor(theme: CustomTheme) { + super(theme); this.position.x = 3; - this.#colors = colors; } getColor(): string { - return this.#colors.tetrisZ; + return this.theme.colors.tetrisZ; } getShapes() { diff --git a/src/screens/Game/components/Cell.js b/src/screens/Game/components/CellComponent.js similarity index 64% rename from src/screens/Game/components/Cell.js rename to src/screens/Game/components/CellComponent.js index 6167e2c..7b952b0 100644 --- a/src/screens/Game/components/Cell.js +++ b/src/screens/Game/components/CellComponent.js @@ -3,28 +3,25 @@ import * as React from 'react'; import {View} from 'react-native'; import {withTheme} from 'react-native-paper'; +import type {CustomTheme} from "../../../managers/ThemeManager"; + +export type Cell = {color: string, isEmpty: boolean, key: string}; type Props = { - item: Object + cell: Cell, + theme: CustomTheme, } -class Cell extends React.PureComponent { - - colors: Object; - - constructor(props) { - super(props); - this.colors = props.theme.colors; - } +class CellComponent extends React.PureComponent { render() { - const item = this.props.item; + const item = this.props.cell; return ( { } -export default withTheme(Cell); +export default withTheme(CellComponent); diff --git a/src/screens/Game/components/Grid.js b/src/screens/Game/components/GridComponent.js similarity index 80% rename from src/screens/Game/components/Grid.js rename to src/screens/Game/components/GridComponent.js index d61af89..0e6092a 100644 --- a/src/screens/Game/components/Grid.js +++ b/src/screens/Game/components/GridComponent.js @@ -3,10 +3,12 @@ import * as React from 'react'; import {View} from 'react-native'; import {withTheme} from 'react-native-paper'; -import Cell from "./Cell"; +import type {Cell} from "./CellComponent"; +import CellComponent from "./CellComponent"; + +export type Grid = Array>; type Props = { - navigation: Object, grid: Array>, backgroundColor: string, height: number, @@ -15,14 +17,7 @@ type Props = { containerMaxWidth: number | string, } -class Grid extends React.Component { - - colors: Object; - - constructor(props) { - super(props); - this.colors = props.theme.colors; - } +class GridComponent extends React.Component { getRow(rowNumber: number) { let cells = this.props.grid[rowNumber].map(this.getCellRender); @@ -39,8 +34,8 @@ class Grid extends React.Component { ); } - getCellRender = (item: Object) => { - return ; + getCellRender = (item: Cell) => { + return ; }; getGrid() { @@ -67,4 +62,4 @@ class Grid extends React.Component { } } -export default withTheme(Grid); +export default withTheme(GridComponent); diff --git a/src/screens/Game/components/Preview.js b/src/screens/Game/components/Preview.js index 48c4442..8313a69 100644 --- a/src/screens/Game/components/Preview.js +++ b/src/screens/Game/components/Preview.js @@ -3,33 +3,25 @@ import * as React from 'react'; import {View} from 'react-native'; import {withTheme} from 'react-native-paper'; -import Grid from "./Grid"; +import type {Grid} from "./GridComponent"; +import GridComponent from "./GridComponent"; type Props = { - next: Object, + items: Array, } class Preview extends React.PureComponent { - colors: Object; - - constructor(props) { - super(props); - this.colors = props.theme.colors; - } - getGrids() { let grids = []; - for (let i = 0; i < this.props.next.length; i++) { - grids.push( - this.getGridRender(this.props.next[i], i) - ); + for (let i = 0; i < this.props.items.length; i++) { + grids.push(this.getGridRender(this.props.items[i], i)); } return grids; } - getGridRender(item: Object, index: number) { - return { }; render() { - if (this.props.next.length > 0) { + if (this.props.items.length > 0) { return ( {this.getGrids()}