Files
rikako-note/react/react文档.md
2023-05-25 00:58:49 +08:00

6.3 KiB
Raw Blame History

快速入门

创建和嵌套组件

React应用由组件组成每个组件都是UI的一部分组件拥有自己的外观和逻辑。

组件是返回标签的js函数

function MyButton() {
  return (
    <button>I'm a button</button>
  );
}

上述已经声明了MyButton组件可以将该组件嵌套到另一个组件中

export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}

react组件必须以大写字母开头而html组件则是必须以小写字母开头可以通过组件开头字母的大小写来区分html组件和react组件

jsx编写标签

上述返回标签的语法被称为jsx大多数react项目都支持jsx。
jsx比html更加严格:

  1. 所有的标签都要有闭合标签(例如<br/>)
  2. 组件不能返回多个标签,只能返回一个标签,如果存在多个,必须将其包含到一个公共的父级<div><>
    function AboutPage() {
         return (
             <>
             <h1>About</h1>
             <p>Hello there.<br />How do you do?</p>
             </>
         );
     }
    

添加样式

React中可以在标签中添加className属性来添加样式其和html中的class工作方式相同

<img className="avatar" />
/* In your CSS */
.avatar {
  border-radius: 50%;
}

显示数据

在jsx中标签位于js中而可以在标签内通过{}来计算js表达式并将其填充到标签中

return (
  <h1>
    {user.name}
  </h1>
);

jsx还可以将表达式的值传递给标签属性通过{}传递表达式的值

return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);

同时可以通过js表达式来复制css

const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}

条件渲染

在React中没有特殊语法编写条件故而可以在js中通过if条件引入jsx

let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);

也可以使用如下方式:

<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>

渲染列表

可以通过如下方式将js数组渲染为列表

const products = [
  { title: 'Cabbage', id: 1 },
  { title: 'Garlic', id: 2 },
  { title: 'Apple', id: 3 },
];
const listItems = products.map(product =>
  <li key={product.id}>
    {product.title}
  </li>
);

return (
  <ul>{listItems}</ul>
);

上述示例中,<li>有一个key属性对于列表中的每个属性都应该传递给其一个字符串或数字的key用于在兄弟节点之间唯一标识该元素。

响应事件

可以在组件中声明事件处理函数来响应事件

function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

更新界面

如果希望组件维护状态信息可以通过导入useState来完成

import { useState } from 'react';

function MyButton() {
  const [count, setCount] = useState(0);

其中count记录当前的状态而setCount则是用于改变状态的函数可以为数组中变量取任何名称。

import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

使用hook

use开头的函数被称为hookuseState是react提供的一个内置hook。
hook比普通函数更为严格只能在组件顶层或其他hook的顶层调用hook。如果想要在条件或循环中使用hook请新建一个组件并在组件内部使用。

组件之间共享数据

如果想要将状态在多个组件之间共享,需要将状态提升存储到最近的公共父组件中

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

此时由MyApp传递给MyButton的值称之为prop

jsx展开传递props

如果父组件想要将接收到的props全部传递给子组件无需在子组件上列出props中全部属性可以使用...props来进行展开

function Profile(props) {
  return (
    <div className="card">
      <Avatar {...props} />
    </div>
  );
}

将jsx作为子组件传递

当采用如下形式时:

<Card>
  <Avatar />
</Card>

其中父组件接收到的prop中children将代表接受到的子组件内容

import Avatar from './Avatar.js';

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

此时想要嵌套在父组件内部的子组件可以通过props.children来访问。

条件渲染

如果在某些条件下组件不想显示任何内容可以返回null

function Item({ name, isPacked }) {
  if (isPacked) {
    return null;
  }
  return <li className="item">{name}</li>;
}