Aula 02 – React – Passando dados por props
Aula 02 – React – Passando dados por props

Tutorial React
Voltar para página principal do blog
Todas as aulas desse curso
Aula 01 Aula 03
Se gostarem do conteúdo dêem um joinha
na página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Hostinger
Digital Ocean
One.com
Melhore seu NETWORKING
Participe de comunidades de desenvolvedores:
Fiquem a vontade para me adicionar ao linkedin.
E também para me seguir no GITHUB.
Ah, se puder, clica na estrela nos meus repositórios pra dá uma força ao meu perfil no GITHUB
Código da branch inicial:
https://github.com/toticavalcanti/tutorial-react/tree/tic_tac_toe
Link da documentação oficial:
https://reactjs.org/tutorial/
Passando dados por props
No método renderSquare do Board, altere o código para passar o props chamado value para o Square:
src/index.js
class Square extends React.Component {
render() {
return (
<button className="square">
{this.props.value}
</button>
)
}
}
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
render() {
const status = 'Next player: X';
return (
React.createElement("div", null,
React.createElement("div", { className: "status" }, status),
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}
}
class Game extends React.Component {
render() {
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, null)),
React.createElement("div", { className: "game-info" },
React.createElement("div", null),
React.createElement("ol", null))));
}
}
// ========================================
ReactDOM.render(
React.createElement(Game, null),
document.getElementById('root'));
Passamos um “props” do componente Board, que é o pai, para um componente filho, o Square.
Preenchendo o componente Square com um “X” quando clicamos nele:
src/index.js
class Square extends React.Component {
render() {
return (
<button className="square" onClick={function() { alert('click'); }}>
{this.props.value}
</button>
)
}
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
render()
const status = 'Next player: X';
return (
React.createElement("div", null,
React.createElement("div", { className: "status" }, status),
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}
}
class Game extends React.Component {
render() {
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, null)),
React.createElement("div", { className: "game-info" },
React.createElement("div", null),
React.createElement("ol", null))));
}
}
// ========================================
ReactDOM.render(
React.createElement(Game, null),
document.getElementById('root'));
Clicando em um quadrado aparecerá um alerta no seu navegador.
Refatorando a onClick para usar arrow function.
src/index.js
class Square extends React.Component {
render() {
return (
<button className="square" onClick={ () => this.setState({value: 'X'}) }>
{this.props.value}
</button>
)
}
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
render()
const status = 'Next player: X';
return (
React.createElement("div", null,
React.createElement("div", { className: "status" }, status),
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}
}
class Game extends React.Component {
render() {
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, null)),
React.createElement("div", { className: "game-info" },
React.createElement("div", null),
React.createElement("ol", null))));
}
}
// ========================================
ReactDOM.render(
React.createElement(Game, null),
document.getElementById('root'));
O próximo passo, é fazer o componente Square lembrar que foi clicado e preencher com um “X”.
Para guardar o estado de clicado, usaremos o estado(state) do componente square.
Os componentes React podem ter estados, configurando o this.state em seus construtores.
O this.state deve ser considerado como privado para o componente React que o definiu.
Vamos armazenar o valor atual do Square em this.state e alterá-lo quando o Square for clicado.
Primeiro, adicionaremos um construtor à classe para inicializar o estado.
Todos os componentes de classe React que possuem um método constructor, devem iniciá-lo com uma chamada super(props).
src/index.js
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button className="square" onClick={ () => this.setState({value: 'X'}) }>
{this.props.value}
</button>
)
}
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
render()
const status = 'Next player: X';
return (
React.createElement("div", null,
React.createElement("div", { className: "status" }, status),
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}
}
class Game extends React.Component {
render() {
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, null)),
React.createElement("div", { className: "game-info" },
React.createElement("div", null),
React.createElement("ol", null))));
}
}
// ========================================
ReactDOM.render(
React.createElement(Game, null),
document.getElementById('root'));
Agora vamos mudar o método render do componente Square para exibir o valor do estado (state) atual quando clicado:
- Substitua this.props.value por this.state.value dentro da tag <button>.
- Coloque props className e onClick em linhas separadas para melhor legibilidade.
Então vamos fazer a modificação e a reidentação.
src/index.js
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button
className="square"
onClick={() => this.setState({value: 'X'})}
>
{this.state.value}
</button>
);
}
}
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
render()
const status = 'Next player: X';
return (
React.createElement("div", null,
React.createElement("div", { className: "status" }, status),
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}
}
class Game extends React.Component {
render() {
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, null)),
React.createElement("div", { className: "game-info" },
React.createElement("div", null),
React.createElement("ol", null))));
}
}
// ========================================
ReactDOM.render(
React.createElement(Game, null),
document.getElementById('root'));
Completando o jogo
Para completar o jogo, precisamos preencher os “X”s e os “O”s no tabuleiro(Board) e de alguma maneira necessitamos definir o vencedor.
Movendo o state para cima
Atualmente, cada componente Square mantém o estado do jogo.
Para verificar o vencedor, a melhor opção é guardar o estado do jogo no componente pai, o tabuleiro.
O componente tabuleiro pode dizer para cada quadrado o que pode ser exibido via props, assim como fizemos quando passamos o número de cada quadrado.
Para coletar dados de múltiplos filhos, ou para fazer dois filhos se comunicarem entre si, você precisa declarar um estado compartilhado em seu componente pai.
O componente pai pode passar o estado de volta para os filhos através do uso de propriedades (props), isso mantém os componentes filhos em sincronia com os seus irmãos e também com o pai.
Criar estado em um componente Pai é bem comum quando componentes React são refatorados.
Vamos aproveitar essa oportunidade para testar o conceito, na prática.
Vamos adicionar um construtor no Tabuleiro e definir que seu estado inicial irá ter um array com 9 posições preenchidas por nulo (null).
Esses 9 nulls corresponderão aos 9 quadrados:
src/index.js
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button
className="square"
onClick={() => this.setState({value: 'X'})}
>
{this.state.value}
</button>
);
}
}
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
};
}
renderSquare(i) {
return <Square value={i} />;
}
render()
const status = 'Next player: X';
return (
React.createElement("div", null,
React.createElement("div", { className: "status" }, status),
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}
}
class Game extends React.Component {
render() {
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, null)),
React.createElement("div", { className: "game-info" },
React.createElement("div", null),
React.createElement("ol", null))));
}
}
// ========================================
ReactDOM.render(
React.createElement(Game, null),
document.getElementById('root'));
Vamos modificar o Tabuleiro para instruir cada Quadrado individualmente qual é o valor correto (‘X’, ‘O’ ou null).
Nós já temos definidos o array de quadrados no construtor do Tabuleiro e iremos modificar o método renderSquare para definir o valor a partir do estado.
Também criar a função handleClick().
Nela, nós chamamos .slice() para criar uma cópia do array de quadrados para o modificar ao invés de fazer no array existente.
Depois a gente vai ver o porquê disso.
src/index.js
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button
className="square"
onClick={() => this.setState({value: 'X'})}
>
{this.state.value}
</button>
);
}
}
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
};
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = 'X';
this.setState({squares: squares});
}
renderSquare(i) {
return <Square value={this.state.squares[i]} />;
}
render()
const status = 'Next player: X';
return (
React.createElement("div", null,
React.createElement("div", { className: "status" }, status),
React.createElement("div", { className: "board-row" },
this.renderSquare(0),
this.renderSquare(1),
this.renderSquare(2)),
React.createElement("div", { className: "board-row" },
this.renderSquare(3),
this.renderSquare(4),
this.renderSquare(5)),
React.createElement("div", { className: "board-row" },
this.renderSquare(6),
this.renderSquare(7),
this.renderSquare(8))));
}
}
class Game extends React.Component {
render() {
return (
React.createElement("div", { className: "game" },
React.createElement("div", { className: "game-board" },
React.createElement(Board, null)),
React.createElement("div", { className: "game-info" },
React.createElement("div", null),
React.createElement("ol", null))));
}
}
// ========================================
ReactDOM.render(
React.createElement(Game, null),
document.getElementById('root'));