小练习

完成画廊组件

当你在最后一个雕塑上按 “Next” 时,代码会发生崩溃。请修复逻辑以防止此崩溃。你可以尝试在事件处理函数中添加额外的逻辑,或在操作无法执行时禁用掉按钮。

修复崩溃后,添加一个显示上一个雕塑的 “Previous” 按钮。同样地,确保它不在第一个雕塑里发生崩溃。

import { useState } from "react";
import { sculptureList } from "./data.js";
export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false)  
  function handleNextClick() {
    setIndex((index + 1) % 12);
  }  
  function handleMoreClick() {
    setShowMore(!showMore);
  }
  function handlePreClick() {
    index == 0 ? setIndex(11) : setIndex((index - 1) % 12);
  }
  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handlePreClick}>Pre</button>
      <button onClick={handleNextClick}>Next</button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
       ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? "Hide" : "Show"} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img src={sculpture.url} alt={sculpture.alt} />
    </>
  );
}

修复一个错误

在 React 中,useState 以及任何其他以“use”开头的函数都被称为 Hook

Hook 是特殊的函数,只在 React 渲染时有效(我们将在下一节详细介绍)。它们能让你 “hook” 到不同的 React 特性中去。

State 只是这些特性中的一个,你之后还会遇到其他 Hook。

陷阱

Hooks ——以 use 开头的函数——只能在组件或自定义 Hook 的最顶层调用。 你不能在条件语句、循环语句或其他嵌套函数内调用 Hook。Hook 是函数,但将它们视为关于组件需求的无条件声明会很有帮助。在组件顶部 “use” React 特性,类似于在文件顶部“导入”模块。

import { useState } from 'react';
 
export default function FeedbackForm() {
  const [isSent, setIsSent] = useState(false);
  //const [message, setMessage] = useState('');只能在最顶层
  if (isSent) {
    return <h1>Thank you!</h1>;
  } else {
    // eslint-disable-next-line
   =============== 不能在这里用Hook!!========================
    const [message, setMessage] = useState('');
    return (
      <form onSubmit={e => {
        e.preventDefault();
        alert(`Sending: "${message}"`);
        setIsSent(true);
      }}>
        <textarea
          placeholder="Message"
          value={message}
          onChange={e => setMessage(e.target.value)}
        />
        <br />
        <button type="submit">Send</button>
      </form>
    );
  }
}
 

reference