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

4.5 KiB
Raw Blame History

id title challengeType forumTopicId
5a24c314108439a4d4036183 在 React Render 方法中使用 JavaScript 6 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组件应该存在并被渲染到页面。

assert.strictEqual(
  Enzyme.mount(React.createElement(MagicEightBall)).find('MagicEightBall')
    .length,
  1
);

MagicEightBall的第一个子元素应该是input元素。

assert.strictEqual(
  Enzyme.mount(React.createElement(MagicEightBall))
    .children()
    .childAt(0)
    .name(),
  'input'
);

MagicEightBall的第三个子元素应该是button元素。

assert.strictEqual(
  Enzyme.mount(React.createElement(MagicEightBall))
    .children()
    .childAt(2)
    .name(),
  'button'
);

MagicEightBall的 state 应该用userInput属性和randomIndex属性初始化,并且这两个属性的值都应该是空字符串。

assert(
  Enzyme.mount(React.createElement(MagicEightBall)).state('randomIndex') ===
    '' &&
    Enzyme.mount(React.createElement(MagicEightBall)).state('userInput') === ''
);

MagicEightBall第一次加载到 DOM 中时,它应该返回一个空的p元素。

assert(
  Enzyme.mount(React.createElement(MagicEightBall)).find('p').length === 1 &&
    Enzyme.mount(React.createElement(MagicEightBall)).find('p').text() === ''
);

当文本被输入到input元素中并点击按钮时,MagicEightBall组件应该返回一个p元素,该元素包含数组possibleAnswers中的随机一个元素。

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--