Background: I'm going through an official React tutorial (https://reactjs.org/tutorial/tutorial.html), but in ReasonML (ReasonReact v. 0.9.1). This is a tic-tac-toe game. The classic game is played on a 3x3 board, and I have it working, but now I'm trying to extend it to an arbitrary square board size. The code I have for the hard-coded 3x3 board looks like follows:
let renderSquare = (...) =>
<Square ... />;
[@react.component]
let make = (~onClick, ~squares, ~winner) => {
...
let render = i =>
renderSquare(...);
<div>
<div className="board-row"> {render(0)} {render(1)} {render(2)} </div>
<div className="board-row"> {render(3)} {render(4)} {render(5)} </div>
<div className="board-row"> {render(6)} {render(7)} {render(8)} </div>
</div>;
The Square
is another component of mine. What I'm trying to achieve is to add an arbitrary amount of Square
s into each row of the board, and to have an arbitrary number of rows.
What I came up with so far doesn't work, because I cannot figure out how to pass an array or a list of React.element
as children to a <div />
. The smallest possible code that shows this problem looks like this:
let renderRow(squares) = <div>(squares |> Array.map(render))</div>;
Here the squares
is of type array(int)
. This function doesn't compile with the following error (the error points to the code inside the div
above):
This has type:
array(React.element)
But somewhere wanted:
React.element
My question is, what is the right way to have an arbitrary number of children to a <div/>
or any other JSX component (not sure if my terminology is straight here). Looks like an array is not the way to go. Is it even possible? If it's not possible, what's the idiomatic way in ReasonReact (or, maybe, just in React) to solve this problem?
There's a function, React.array
, that you need to use to convert an array of elements into a single element:
let renderRow(squares) = <div>(squares |> Array.map(render) |> React.array)</div>;