Where does passed arguments saved in a rendered react component

2093 views javascript
0

I was following some tutorials on react web-site and tried some example code included. Here's the link for that code in codepen

https://codepen.io/gaearon/pen/gWWZgR?editors=0010

Here are some snippets to the problem

<div className="board-row">
    {this.renderSquare(0)}
    {this.renderSquare(1)}
    {this.renderSquare(2)}
</div>

This will call the renderSquare method passing a number as an argument so this will be helpful for identifying onClick method depending on the square (Which is a button).

Here's the renderSquare method

renderSquare(i) {
        console.log(<Square/>);
        return (
            <Square
                value={this.props.squares[i]}
                onClick={() => this.props.onClick(i)}
            />
        );
    }

and this method calls a functional component Square,

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

    );
}

So when a square is clicked it will calls to handleClick(i) method (Better to see codepen link so you'll understand the whole code)

handleClick(i) {
        console.log(i);
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1];
        const squares = current.squares.slice();
        if (calculateWinner(squares) || squares[i]) {
            return;
        }
        squares[i] = this.state.xIsNext ? "X" : "O";
        this.setState({
            history: history.concat([{
                squares: squares,
            }]),
            stepNumber: history.length,
            xIsNext: !this.state.xIsNext,
        });
    }

So by using that console.log (Not in codepen code), when I click a button (tic-tac-toe game, so 9 buttons) it will shows the argument which is passed (0,1,2...8).

So my question is where these numbers are stored in those rendered react components? I tried console logging Square component but I couldn't find that argument. (This is not related to props or state)

answered question

2 Answers

13

in the handleClick method, log out history and you'll see the data is saved in state, in this case this.state.history. try this:

handleClick(i) {
    const history = this.state.history.slice(0, this.state.stepNumber + 1);
    const current = history[history.length - 1];
    console.log('history:', history)

posted this
10

So my question is where these numbers are stored in those rendered react components?

This has nothing to with React. It's how functions work in JavaScript.

Whenever a function is a called, a new environment is created. An environment is an internal data structure to keep state. The values of parameters and variables are stored in that environment.

For example consider the function:

function foo(bar) {
  var baz = 42;
}

foo(21);

When foo is called, a new environment is created with the two entries:

bar: 21
baz: 42

In your code, every time renderSquare is called, a new environment is created with an entry i.


Closures are functions which can resolve variables that are not defined in itself. Consider the following example:

function add(x) {
  return function innerAdd(y) {
    return x + y;
  }
}

var add5 = add(5);
add5(2); // 7

Here, innerAdd is a function references x, but x is not defined inside itself.

When add is executed, a new environment is created with

x: 5

innerAdd has a reference to that environment! So when add5/innerAdd is executed, it can look up x in that environment. You think of the environments be linked together:

<innerAdd environment>
y: 2
parenEnvironment:
  <add environment>
  x: 5

Exactly the same happens with the event handler that you are creating inside renderSquare. The event handler is a function that is created inside an environment where i=0 (and/or i=1, i=2, etc).


See also How do JavaScript closures work?

posted this

Have an answer?

JD

Please login first before posting an answer.