Artigo original: React - Change Inline CSS Conditionally Based on Component State
Se você estiver com problemas com o desafio Mudar CSS em linha condicionalmente com base no estado do componente do freeCodeCamp, provavelmente, não está sozinho.
Nesse desafio, você precisa adicionar código para alterar de modo condicional o CSS em linha com base no estado, ou state, de um componente do React.
Ao chegar ao desafio, este é o código que você verá:
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Altere o código abaixo desta linha
// Altere o código acima desta linha
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
Perceba que um objeto de estilo em linha, chamado inputStyle
, já foi declarado com estilização padrão.
Seu objetivo nesse desafio é atualizar inputStyle
de maneira que a borda do elemento input
seja 3px solid red
quando houver mais de 15 caracteres na entrada. Observe que o texto na caixa de entrada é salvo no state do componente como input
:
...
this.state = {
input: ''
};
...
Quase lá, mas ainda não está certo
Imagine que, após ler a descrição e as instruções, você tenha essa ideia:
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Altere o código abaixo desta linha
const char = 15;
if(this.state.input > char) {
inputStyle = {
border:'3px solid red'
}
}
// Altere o código acima desta linha
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
Ao tentar enviar, porém, o código não passa em todos os testes. Vamos examinar mais de perto o que está havendo.
Soluções
Usando uma instrução if
Declarar char
é uma boa ideia, mas examine a condição no bloco if
:
if(this.state.input > char) {
inputStyle = {
border:'3px solid red'
}
}
Lembre-se de que this.state.input
é o valor da caixa de entrada e que é uma string. Por exemplo, ela pode ser "testando testando 1, 2, 3".
Se você inserir "testando testando 1, 2, 3" na caixa de texto e se registrar this.state.input
no console (usando console.log
):
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Altere o código abaixo desta linha
const char = 15;
console.log(this.state.input);
if(this.state.input > char) {
inputStyle = {
border:'3px solid red'
}
}
// Altere o código acima desta linha
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
Você verá testando testando 1, 2, 3
no console.
Além disso, se você registrar this.state.input > char
no console, verá que seu valor é false
:
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Altere o código abaixo desta linha
const char = 15;
console.log(this.state.input > char);
if(this.state.input > char) {
inputStyle = {
border:'3px solid red'
}
}
// Altere o código acima desta linha
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
Dito de maneira simplificada, não é possível comparar uma string (this.state.input
) diretamente com char
, que é um número.
Em vez disso, chame .length
em this.state.input
para obter o tamanho da string e compare-o a count
:
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Altere o código abaixo desta linha
const char = 15;
if(this.state.input.length > char) {
inputStyle = {
border:'3px solid red'
}
}
// Altere o código acima desta linha
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
Como o tamanho da string "testando testando 1, 2, 3" é de 23 caracteres (incluindo espaços e vírgulas), a borda da caixa de entrada deverá ser vermelha:
Usando um operador ternário
Um operador ternário ou condicional é como uma instrução if...else
de apenas uma linha, o que pode ajudar você a reduzir significativamente o tamanho do seu código.
Volte agora à sua solução e remova tudo, exceto a variável char
:
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Altere o código abaixo desta linha
// Altere o código acima desta linha
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
Agora, pegue a condição que você usou na sua instrução if
de antes e use-a na primeira parte do operador ternário: this.state.input.length > char ? : ;
Tudo o que estiver entre ?
e :
indica o que ocorrerá se a instrução retornar true
. Você pode simplesmente copiar o código que estava dentro da instrução if
de antes: this.state.input.length > char ? inputStyle = { border:'3px solid red' } : ;
Depois disso, você precisa lidar com a parte do else
do operador ternário, que é tudo o que se encontra entre :
e ;
.
Embora você não tenha usado uma instrução else
na sua primeira solução, você conseguiu usar inputStyle
como estava de modo eficaz. Assim, basta usar inputStyle
do modo como foi declarado anteriormente no código: this.state.input.length > char ? inputStyle = { border:'3px solid red' } : inputStyle;
Sua solução completa deverá ter esta aparência:
class GateKeeper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ input: event.target.value })
}
render() {
let inputStyle = {
border: '1px solid black'
};
// Altere o código abaixo desta linha
const char = 15;
this.state.input.length > char ? inputStyle = { border:'3px solid red' } : inputStyle;
// Altere o código acima desta linha
return (
<div>
<h3>Don't Type Too Much:</h3>
<input
type="text"
style={inputStyle}
value={this.state.input}
onChange={this.handleChange} />
</div>
);
}
};
Está resolvido – agora, você deve ser capaz de passar no desafio! Agora, você já sabe como estilizar de modo condicional os componentes do React da maneira que quiser.