Home > Blockchain >  Parent state is undefined from grand child component
Parent state is undefined from grand child component

Time:10-02

I am trying to call parent function from grand child component and inside that function setting the parent state. when i try to access parent state inside that function it returns undefined. I tried putting board inside dependency array of useEffect i can access board state if the useEffect is empty but as soon as i call the function inside useEffect it again became undefined. Please help me understand why it is undefined and how should i access it.

Parent Component

 const [board, setBoard] = useState([
    EMPTY,
    EMPTY,
    EMPTY,
    EMPTY,
    EMPTY,
    EMPTY,
    EMPTY,
    EMPTY,
    EMPTY,
  ]);

  const _populateTile = (index, figure, onFinish = f => f) => {
    // undefined board
    if (board[index] !== EMPTY) {
      return;
    }

    const board = [...board];
    board[index] = figure;

    setBoard(board);

    const result = _judgeWinner();

    if (result !== null) {
      props.onFinish(result);
    }

    onFinish();
  };

  const _handlePress = index => {
    _populateTile(index, PLAYER_FIGURE, () => _AIAct());
  };

return (
    <View>
      <Board board={board} onPress={_handlePress} />
    </View>
  );

Child Component

const Board = props => {
  function _renderRows() {
    const rows = [];

    for (let i = 0; i < 3;   i) {
      rows.push(
        <View key={i} style={styles.row}>
          {_renderRow(i)}
        </View>,
      );
    }

    return rows;
  }

  function _renderRow(number) {
    const tiles = [];
    const {board = [], onPress} = props;

    for (let i = 0; i < 3;   i) {
      const index = number * 3   i;

      tiles.push(
        <Tile key={i} value={board[index]} index={index} onPress={onPress} />,
      );
    }

    return tiles;
  }
  return <View style={styles.container}>{_renderRows()}</View>;
};

Grand Child Component

const Tile = props => {
  const _renderContent = () => {
    switch (props.value) {
      case CIRCLE:
        return <Entypo size={ICON_SIZE / 2} name="circle" color="white" />;
      case CROSS:
        return <Entypo size={ICON_SIZE / 2} name="cross" color="white" />;
      default:
        return <Text style={styles.text} onPress={_handlePress} />;
    }
  };

  const _handlePress = () => {
    props.onPress(props.index);
  };
  return <View style={styles.container}>{_renderContent()}</View>;
};

CodePudding user response:

Because you call local board variable before it was defined.

Change this code block:

// undefined board
if (board[index] !== EMPTY) {
  return;
}

const board = [...board];
board[index] = figure;

setBoard(board);

Into:

// defined board state
if (board[index] !== EMPTY) {
  return;
}

const _board = [...board];
_board[index] = figure;

setBoard(_board);

You can see the demo in this CodeSandbox: https://codesandbox.io/s/quizzical-wilson-hqwfc

  • Related