Skip to content

allons-y#1

Open
julian-carvajal-gh wants to merge 4 commits intoThe-Marcy-Lab-School:masterfrom
julian-carvajal-gh:master
Open

allons-y#1
julian-carvajal-gh wants to merge 4 commits intoThe-Marcy-Lab-School:masterfrom
julian-carvajal-gh:master

Conversation

@julian-carvajal-gh
Copy link

No description provided.

}

// what are better solutions for this?
class Ids {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are Id's here for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keys 😅 My items didn't have any unique identifiers and I didn't like the warning for using index.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a clever solution to this problem. To be honest, I'd have probably just stuck with the indices in this case. Using indices for keys can cause issues if the order of the array changes, but in your case those should be pretty static.

Copy link

@erwinssaget erwinssaget left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. You did a great job, and your code is nicely formatted.

@ROgbonna1 ROgbonna1 assigned ipc103 and unassigned erwinssaget May 13, 2020
Copy link

@ipc103 ipc103 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @emtes - really nice work on this one! The feature works really well, and I like how you organized the different components of the application. I left a few comments/ideas in-line, feel free to respond with any questions you might have!

);
}

function NoughtsCrosses() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to keep things organized, I'd recommend separating each component out into a separate file. Not a big deal, but it can help make the project easier to navigate for folks coming in fresh.

<h2>History</h2>
{history.length > 1 && (
<p>
Hi being of the multiverse! Please go to most recent move before continuing to play.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 nice message here! One thing that might be nice is to have a separate piece of state to determine if the user is viewing history on the parent component. That way, you could disable the selecting of squares until they went back to the top of the timeline.

}

// what are better solutions for this?
class Ids {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a clever solution to this problem. To be honest, I'd have probably just stuck with the indices in this case. Using indices for keys can cause issues if the order of the array changes, but in your case those should be pretty static.

...game,
board: newBoard,
isXNext: !isXNext,
history: [...history, [...newBoard]],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definitely works.Instead of storing the entire board at each state, you could also keep track of what square was played at each turn. So, you could imagine your history looking something like [{turn: 1, played: 'X', cell: 4}, {turn: 2, played: 'O', cell: 0}] or something like that. Totally your call! In this case, I think the only tradeoff you really need to consider is readability.

function NoughtsCrosses() {
const defaultGame = {
board: Array(9).fill(null),
isXNext: true,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be more inclined to store the currentPlayer as a string I think. Then, you could avoid needing to use the ternary to render the correct string.

);
}

function Board({ board, handlePlay }) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work splitting up the concerns between these different components - makes it really easy to re-use your Board component when rendering the history.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you talk more about reusability? Does it refer to reusing components for different projects? What makes components reusable? Thanks!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! Re-use probably wasn't the right word, but in this case the Board component is pretty flexible. You pass it an array of values and it will render out the game board for you. This means that, when you use the history component to change what the board should look like, it just re-renders itself. So I guess this is more about separation of concerns than re-usability. This component knows about just the right amount of stuff. Let me know if that clarifies things a little bit!

isXNext: true,
history: [Array(9).fill(null)],
};
const [game, setGame] = useState(defaultGame);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using useState here definitely works. This component is easy to read and follow what's happening. One potential advantage to using useReducer is your reducer function could store a lot of the logic around checking for the winner and updating the board and the history. In this case, this component didn't get too big so I think this works well as-is.

);
}

function getWinner(board) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a previous comment, I mentioned splitting up the components into separate files. For functions like this, sometimes I'll create a util directory and store shared-logic in that component. Either way, I like keeping this grouped in a separate function.

@ipc103 ipc103 removed their assignment Apr 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants