WHAT - React 学习系列(一)

官方文档

If you have a lot of HTML to port to JSX, you can use an online converter.

You'll get two things from useState: the current state (count), and the function that lets you update it (setCount).

  • To "remember" things, components use state.
  • To make the UI interactive, you need to let users change your underlying data model. You will use state for this.

Which of these are state? Identify the ones that are not:

  • Does it remain unchanged over time? If so, it isn't state.
  • Is it passed in from a parent via props? If so, it isn't state.
  • Can you compute it based on existing state or props in your component? If so, it definitely isn't state!

After identifying your app's minimal state data, you need to identify which component is responsible for changing this state, or owns the state .

For each piece of state in your application:

  • Identify every component that renders something based on that state.
  • Find their closest common parent component---a component above them all in the hierarchy.
  • Decide where the state should live:
  • Often, you can put the state directly into their common parent.
  • You can also put the state into some component above their common parent.
  • If you can't find a component where it makes sense to own the state, create a new component solely for holding the state and add it somewhere in the hierarchy above the common parent component.

You can find other built-in Hooks in the API reference.

Hooks are more restrictive than other functions. You can only call Hooks at the top of your components (or other Hooks). If you want to use useState in a condition or a loop, extract a new component and put it there.

A JSX element is a combination of JavaScript code and HTML tags that describes what you'd like to display.

To "escape into JavaScript" from JSX, you need curly braces. Add curly braces around value in JSX like so:

javascript 复制代码
function Square({ value }) {
  return <button className="square">{value}</button>;
}

React DevTools let you check the props and the state of your React components.

When you were passing onSquareClick={handleClick}, you were passing the handleClick function down as a prop. You were not calling it! But now you are calling that function right away---notice the parentheses in handleClick(0) --- and that's why it runs too early. You don't want to call handleClick until the user clicks! Instead, let's do this: <Square value={squares[0]} onSquareClick={() => handleClick(0)} />. Notice the new () => syntax. Here, () => handleClick(0) is an arrow function, which is a shorter way to define functions.

In React, it's conventional to use onSomething names for props which represent events and handleSomething for the function definitions which handle those events.

**Why immutability is important?**Note how in handleClick, you call .slice() to create a copy of the squares array instead of modifying the existing array?
https://react.dev/learn/tutorial-tic-tac-toe#why-immutability-is-important

You can learn more about how React chooses when to re-render a component in the memo API reference.
https://react.dev/reference/react/memo

When you render a list, React stores some information about each rendered list item. When you update a list, React needs to determine what has changed. You could have added, removed, re-arranged, or updated the list's items. React is a computer program and does not know what you intended, so you need to specify a key property for each list item to differentiate each list item from its siblings. When a list is re-rendered, React takes each list item's key and searches the previous list's items for a matching key . If the current list has a key that didn't exist before, React creates a component. If the current list is missing a key that existed in the previous list, React destroys the previous component. If two keys match, the corresponding component is moved.
https://react.dev/learn/tutorial-tic-tac-toe#picking-a-key

Using the array index as a key is problematic when trying to re-order a list's items or inserting/removing list items?

To implement a UI in React, you will usually follow the same five steps.

Step 1: Break the UI into a component hierarchy

Step 2: Build a static version in React

Step 3: Find the minimal but complete representation of UI state

Step 4: Identify where your state should live

Step 5: Add inverse data flow

https://react.dev/learn/thinking-in-react

In simpler examples, it's usually easier to go top-down, and on larger projects, it's easier to go bottom-up.

You can learn all about handling events and updating state in the Adding Interactivity section.
https://react.dev/learn/adding-interactivity

  • Responding to events
  • State: a component's memory
  • Render and commit
  • State as a snapshot
  • Queueing a series of state updates
  • Updating objects in state
  • Updating arrays in state

state as a snapshot:

javascript 复制代码
console.log(count);  // 0
setCount(count + 1); // Request a re-render with 1
console.log(count);  // Still 0!

Read State as a Snapshot to learn why state appears "fixed" and unchanging inside the event handlers.
https://react.dev/learn/state-as-a-snapshot

updater function:

javascript 复制代码
console.log(score);  // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score);  // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score);  // 0
setScore(score + 1); // setScore(0 + 1);
console.log(score);  // 0

can fix this by passing an updater function when setting state.

javascript 复制代码
function increment() {
  setScore(s => s + 1);
}

update objects:

Usually, you will use the ... spread syntax to copy objects and arrays that you want to change.

javascript 复制代码
  const [person, setPerson] = useState({
    name: 'Niki de Saint Phalle',
    artwork: {
      title: 'Blue Nana',
      city: 'Hamburg',
      image: 'https://i.imgur.com/Sd1AgUOm.jpg',
    }
  });
  function handleNameChange(e) {
    setPerson({
      ...person,
      name: e.target.value
    });
  }
  function handleTitleChange(e) {
    setPerson({
      ...person,
      artwork: {
        ...person.artwork,
        title: e.target.value
      }
    });
  }

If copying objects in code gets tedious, you can use a library like Immer to reduce repetitive code:
GitHub - immerjs/use-immer: Use immer to drive state with a React hooks

javascript 复制代码
  import { useImmer } from 'use-immer';
  const [person, updatePerson] = useImmer({
    name: 'Niki de Saint Phalle',
    artwork: {
      title: 'Blue Nana',
      city: 'Hamburg',
      image: 'https://i.imgur.com/Sd1AgUOm.jpg',
    }
  });
  function handleNameChange(e) {
    updatePerson(draft => {
      draft.name = e.target.value;
    });
  }
  function handleTitleChange(e) {
    updatePerson(draft => {
      draft.artwork.title = e.target.value;
    });
  }

update arrays:

Arrays are another type of mutable JavaScript objects you can store in state and should treat as read-only.

javascript 复制代码
  const [list, setList] = useState(
    initialList
  );
  function handleToggle(artworkId, nextSeen) {
    setList(list.map(artwork => {
      if (artwork.id === artworkId) {
        return { ...artwork, seen: nextSeen };
      } else {
        return artwork;
      }
    }));
  }

If copying arrays in code gets tedious, you can use a library like Immer to reduce repetitive code:

javascript 复制代码
import { useImmer } from 'use-immer';
const [list, updateList] = useImmer(initialList);
  function handleToggle(artworkId, nextSeen) {
    updateList(draft => {
      const artwork = draft.find(a =>
        a.id === artworkId
      );
      artwork.seen = nextSeen;
    });
  }
相关推荐
知识分享小能手1 小时前
高等数学学习教程,从入门到精通,定积分 — 知识点全面总结(10)
学习·机器学习·概率论
weixin_382395237 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__8 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.8 小时前
Vue3 Props 属性
前端·javascript·vue.js
暗影凋落9 小时前
CMake构建学习笔记-SQLite库的构建
笔记·学习·sqlite
醉城夜风~9 小时前
CSS元素显示模式(display)
前端·css
画面无声10 小时前
STM32的SPI通信原理与练习记录
c语言·stm32·单片机·嵌入式硬件·学习
AI大模型-小华10 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
你有哈莫吗10 小时前
CMake构建学习笔记-iconv库的构建
笔记·学习
ctlover11 小时前
Python学习第4日
学习