freeCodeCamp/curriculum/challenges/chinese/03-front-end-libraries/react/use-advanced-javascript-in-...

157 lines
4.5 KiB
Markdown
Raw Normal View History

---
id: 5a24c314108439a4d4036183
title: 在 React Render 方法中使用 JavaScript
challengeType: 6
forumTopicId: 301415
---
# --description--
在之前的挑战中,你学习了如何使用大括号`{ }`将 JavaScript 代码插入到 JSX 代码中,用于访问 props、传递 props、访问 state、在代码中插入注释以及最近学习的定制组件样式等任务。这些都是将 JavaScript 放在 JSX 中的常见用例,但是在 React 组件中使用 JavaScript 代码还有其他方式。
在`render`方法中编写 JavaScript你可以把 JavaScript 直接放在`return`语句之前,而***不必***将其插入大括号中。这是因为它还不在 JSX 代码中。当你稍后想在`return`语句中的 JSX 代码中使用变量时,可以将变量名放在大括号中。
# --instructions--
在提供的代码中,`render`方法中有一个包含 20 个短语的数组,用于表示 20 世纪 80 年代经典魔术八球玩具中的答案。绑定`ask`方法到按钮的单击事件,每次单击该按钮时,将生成随机数并将其存储为 state 中的`randomIndex`。在第 52 行,删除字符串`"change me!"`并重新分配`answer`常量,以便每次组件更新时,你的代码随机访问`possibleAnswers`数组的不同索引。最后,在`p`标签内插入`answer`常量。
# --hints--
`MagicEightBall`组件应该存在并被渲染到页面。
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall)).find('MagicEightBall')
.length,
1
);
```
`MagicEightBall`的第一个子元素应该是`input`元素。
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall))
.children()
.childAt(0)
.name(),
'input'
);
```
`MagicEightBall`的第三个子元素应该是`button`元素。
```js
assert.strictEqual(
Enzyme.mount(React.createElement(MagicEightBall))
.children()
.childAt(2)
.name(),
'button'
);
```
`MagicEightBall`的 state 应该用`userInput`属性和`randomIndex`属性初始化,并且这两个属性的值都应该是空字符串。
```js
assert(
Enzyme.mount(React.createElement(MagicEightBall)).state('randomIndex') ===
'' &&
Enzyme.mount(React.createElement(MagicEightBall)).state('userInput') === ''
);
```
当`MagicEightBall`第一次加载到 DOM 中时,它应该返回一个空的`p`元素。
```js
assert(
Enzyme.mount(React.createElement(MagicEightBall)).find('p').length === 1 &&
Enzyme.mount(React.createElement(MagicEightBall)).find('p').text() === ''
);
```
当文本被输入到`input`元素中并点击按钮时,`MagicEightBall`组件应该返回一个`p`元素,该元素包含数组`possibleAnswers`中的随机一个元素。
```js
async () => {
const waitForIt = (fn) =>
new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250));
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 waitForIt(() => result());
};
const _2 = () => {
simulate();
return waitForIt(() => result());
};
const _3 = () => {
simulate();
return waitForIt(() => result());
};
const _4 = () => {
simulate();
return waitForIt(() => result());
};
const _5 = () => {
simulate();
return waitForIt(() => result());
};
const _6 = () => {
simulate();
return waitForIt(() => result());
};
const _7 = () => {
simulate();
return waitForIt(() => result());
};
const _8 = () => {
simulate();
return waitForIt(() => result());
};
const _9 = () => {
simulate();
return waitForIt(() => result());
};
const _10 = () => {
simulate();
return waitForIt(() => result());
};
const _1_val = await _1();
const _2_val = await _2();
const _3_val = await _3();
const _4_val = await _4();
const _5_val = await _5();
const _6_val = await _6();
const _7_val = await _7();
const _8_val = await _8();
const _9_val = await _9();
const _10_val = await _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);
};
```
# --solutions--