tictactoe项目
郭旭升 Lv6

目标

一个互动的井字棋游戏

concepts(React)

elements, components, props, and state

技术点

  • what is a component?
    In React, a component is a piece of reusable code that represents a part of a user interface. Components are used to render, manage, and update the UI elements in your application.

  • key word:
    export: The export JavaScript keyword makes this function accessible outside of this file.
    default: The default keyword tells other files using your code that it’s the main function in your file.
    return: The return JavaScript keyword means whatever comes after is returned as a value to the caller of the function.

  • what is a JSX element?
    A JSX element is a combination of JavaScript code and HTML tags that describes what you’d like to display.

  • what can be return in React components?
    React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use fragments (<> and </>) to wrap multiple adjacent JSX elements

passing value through props

1
2
3
4
5
<Square value="1" />

function Square({ value }) {
return <button className="square">{value}</button>;
}

state to remember

To “remember” things, components use state.
React provides a special function called useState that you can call from your component to let it “remember” things.

1
2
3
4
5
import { useState } from 'react';

function Square() {
const [value, setValue] = useState(null);
}

add a new line at the start of the Square that calls useState. Have it return a state variable called value
value stores the value and setValue is a function that can be used to change the value.
The null passed to useState is used as the initial value for this state variable, so value here starts off equal to null.

Each Square has its own state: the value stored in each Square is completely independent of the others. When you call a set function in a component, React automatically updates the child components inside too.

manage the states of mutible children

To collect data from multiple children, or to have two child components communicate with each other, declare the shared state in their parent component instead. The parent component can pass that state back down to the children via props. This keeps the child components in sync with each other and with their parent.

Lifting state into a parent component is common when React components are refactored.

Immutability

  • Avoiding direct data mutation lets you keep previous versions of the data intact, and reuse them later.

  • Immutability makes it very cheap for components to compare whether their data has changed or not. You can learn more about how React chooses when to re-render a component in the memo API reference.(https://zh-hans.reactjs.org/reference/react/memo)

Taking turns

Let’s keep track of this by adding another piece of state.

1
2
3
4
5
6
function Board() {
const [xIsNext, setXIsNext] = useState(true);
const [squares, setSquares] = useState(Array(9).fill(null));

// ...
}

Adding time travel

  1. store the history
  2. Lifting state up, again - write a new top-level component called Game to display a list of past moves. That’s where you will place the history state that contains the entire game history.

This gives the Game component full control over the Board’s data and lets it instruct the Board to render previous turns from the history.
3. add a key
each past move has a unique ID associated with it: it’s the sequential number of the move. Moves will never be re-ordered, deleted, or inserted in the middle, so it’s safe to use the move index as a key.

key in components

When a list is re-rendered, React takes each list item’s key and searches the previous list’s items for a matching key. If the current list has a key that didn’t exist before, React creates a component. If the current list is missing a key that existed in the previous list, React destroys the previous component. If two keys match, the corresponding component is moved.

Keys tell React about the identity of each component, which allows React to maintain state between re-renders. If a component’s key changes, the component will be destroyed and re-created with a new state.

key is a special and reserved property in React. When an element is created, React extracts the key property and stores the key directly on the returned element. Even though key may look like it is passed as props, React automatically uses key to decide which components to update. There’s no way for a component to ask what key its parent specified.

It’s strongly recommended that you assign proper keys whenever you build dynamic lists. If you don’t have an appropriate key, you may want to consider restructuring your data so that you do.

If no key is specified, React will report an error and use the array index as a key by default. Using the array index as a key is problematic when trying to re-order a list’s items or inserting/removing list items. Explicitly passing key={i} silences the error but has the same problems as array indices and is not recommended in most cases.

Keys do not need to be globally unique; they only need to be unique between components and their siblings.

achivement now

  • Lets you play tic-tac-toe,
  • Indicates when a player has won the game,
  • Stores a game’s history as a game progresses,
  • Allows players to review a game’s history and see previous versions of a game’s board.
  • For the current move only, show “You are at move #…” instead of a button.
  • Rewrite Board to use two loops to make the squares instead of hardcoding them.
  • Add a toggle button that lets you sort the moves in either ascending or descending order.
  • When someone wins, highlight the three squares that caused the win (and when no one wins, display a message about the result being a draw).
  • Display the location for each move in the format (row, col) in the move history list.
 Comments