8.3 KiB
id | title | challengeType | forumTopicId | dashedName |
---|---|---|---|---|
5a24c314108439a4d4036183 | Usa JavaScript avanzado en el método render de React | 6 | 301415 | use-advanced-javascript-in-react-render-method |
--description--
En desafíos anteriores, aprendiste cómo inyectar código JavaScript en código JSX usando llaves, { }
, para tareas como acceder a props, pasar props, acceder al state, insertar comentarios en tu código y, más recientemente, diseñar tus componentes. Todos estos son casos de uso común para poner JavaScript en JSX, pero no son la única manera de utilizar código JavaScript en tus componentes React.
También puedes escribir JavaScript directamente en los métodos render
, antes de la sentencia return
, sin insertarlo dentro de llaves. Esto es porque aún no está dentro del código JSX. Cuando quieras utilizar una variable en el código JSX dentro de la sentencia return
, colocas el nombre de la variable dentro de llaves.
--instructions--
En el código proporcionado, el método render
tiene un arreglo que contiene 20 frases para representar las respuestas encontradas en el clásico juego "Magic Eight Ball" de los años ochenta. El evento clic del botón está vinculado al método ask
, por lo que cada vez que se haga clic en el botón se generará un número aleatorio y se almacenará como el randomIndex
en el state. En la línea 52, elimina la cadena change me!
y reasigna la constante answer
para que tu código acceda aleatoriamente a un índice diferente del arreglo possibleAnswers
cada vez que se actualiza el componente. Finalmente, inserta la constante answer
dentro de las etiquetas p
.
--hints--
El componente MagicEightBall
debe existir y renderizarse en la página.
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall)).find('MagicEightBall')
.length,
1
);
El primer elemento hijo de MagicEightBall
debe ser un elemento input
.
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall))
.children()
.childAt(0)
.name(),
'input'
);
El tercer elemento hijo de MagicEightBall
debe ser un elemento button
.
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall))
.children()
.childAt(2)
.name(),
'button'
);
El estado de MagicEightBall
debe inicializarse con una propiedad de userInput
y una propiedad de randomIndex
juntas establecidas como cadenas de texto vacías.
assert(
Enzyme.mount(React.createElement(MagicEightBall)).state('randomIndex') ===
'' &&
Enzyme.mount(React.createElement(MagicEightBall)).state('userInput') === ''
);
Cuando MagicEightBall
se monte por primera vez en el DOM, debe devolver un elemento p
vacío.
assert(
Enzyme.mount(React.createElement(MagicEightBall)).find('p').length === 1 &&
Enzyme.mount(React.createElement(MagicEightBall)).find('p').text() === ''
);
Cuando se introduce texto en el elemento input
y se hace clic en el botón, el componente MagicEightBall
debe devolver un elemento p
que contiene un elemento aleatorio del arreglo possibleAnswers
.
(() => {
const comp = Enzyme.mount(React.createElement(MagicEightBall));
const simulate = () => {
comp.find('input').simulate('change', { target: { value: 'test?' } });
comp.find('button').simulate('click');
};
const result = () => comp.find('p').text();
const _1 = () => {
simulate();
return result();
};
const _2 = () => {
simulate();
return result();
};
const _3 = () => {
simulate();
return result();
};
const _4 = () => {
simulate();
return result();
};
const _5 = () => {
simulate();
return result();
};
const _6 = () => {
simulate();
return result();
};
const _7 = () => {
simulate();
return result();
};
const _8 = () => {
simulate();
return result();
};
const _9 = () => {
simulate();
return result();
};
const _10 = () => {
simulate();
return result();
};
const _1_val = _1();
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
const _5_val = _5();
const _6_val = _6();
const _7_val = _7();
const _8_val = _8();
const _9_val = _9();
const _10_val = _10();
const actualAnswers = [
_1_val,
_2_val,
_3_val,
_4_val,
_5_val,
_6_val,
_7_val,
_8_val,
_9_val,
_10_val
];
const hasIndex = actualAnswers.filter(
(answer, i) => possibleAnswers.indexOf(answer) !== -1
);
const notAllEqual = new Set(actualAnswers);
assert(notAllEqual.size > 1 && hasIndex.length === 10);
})();
--seed--
--after-user-code--
var possibleAnswers = [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes, definitely',
'You may rely on it',
'As I see it, yes',
'Outlook good',
'Yes',
'Signs point to yes',
'Reply hazy try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
"Don't count on it",
'My reply is no',
'My sources say no',
'Outlook not so good',
'Very doubtful',
'Most likely'
];
ReactDOM.render(<MagicEightBall />, document.getElementById('root'));
--seed-contents--
const inputStyle = {
width: 235,
margin: 5
};
class MagicEightBall extends React.Component {
constructor(props) {
super(props);
this.state = {
userInput: '',
randomIndex: ''
};
this.ask = this.ask.bind(this);
this.handleChange = this.handleChange.bind(this);
}
ask() {
if (this.state.userInput) {
this.setState({
randomIndex: Math.floor(Math.random() * 20),
userInput: ''
});
}
}
handleChange(event) {
this.setState({
userInput: event.target.value
});
}
render() {
const possibleAnswers = [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes, definitely',
'You may rely on it',
'As I see it, yes',
'Outlook good',
'Yes',
'Signs point to yes',
'Reply hazy try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
"Don't count on it",
'My reply is no',
'My sources say no',
'Most likely',
'Outlook not so good',
'Very doubtful'
];
const answer = 'change me!'; // Change this line
return (
<div>
<input
type='text'
value={this.state.userInput}
onChange={this.handleChange}
style={inputStyle}
/>
<br />
<button onClick={this.ask}>Ask the Magic Eight Ball!</button>
<br />
<h3>Answer:</h3>
<p>
{/* Change code below this line */}
{/* Change code above this line */}
</p>
</div>
);
}
}
--solutions--
const inputStyle = {
width: 235,
margin: 5
};
class MagicEightBall extends React.Component {
constructor(props) {
super(props);
this.state = {
userInput: '',
randomIndex: ''
};
this.ask = this.ask.bind(this);
this.handleChange = this.handleChange.bind(this);
}
ask() {
if (this.state.userInput) {
this.setState({
randomIndex: Math.floor(Math.random() * 20),
userInput: ''
});
}
}
handleChange(event) {
this.setState({
userInput: event.target.value
});
}
render() {
const possibleAnswers = [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes, definitely',
'You may rely on it',
'As I see it, yes',
'Outlook good',
'Yes',
'Signs point to yes',
'Reply hazy try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
"Don't count on it",
'My reply is no',
'My sources say no',
'Outlook not so good',
'Very doubtful',
'Most likely'
];
const answer = possibleAnswers[this.state.randomIndex];
return (
<div>
<input
type='text'
value={this.state.userInput}
onChange={this.handleChange}
style={inputStyle}
/>
<br />
<button onClick={this.ask}>Ask the Magic Eight Ball!</button>
<br />
<h3>Answer:</h3>
<p>{answer}</p>
</div>
);
}
}