React 组件通信与插槽学习笔记

80 阅读2分钟
  1. DOM组件props中,设置类名时需使用 className :<img className="image" />;
  2. 进行多属性props设置时,可以使用jsx展开语法(注意img中的alt不可以单独提出来,jsx展开语法与展开运算符不同,展开运算符需要容器)
import image from './logo.svg';

function App(params) {
  const imageData = {
    className: 'small',
    style: {
      width: 200,
      height: 200,
      backgroundColor: 'grey'
    }
  }
  return (
    <div>
      <img
        src = {image}
        alt = ""
        {...imageData}
      />
    </div>
  )
}


export default App;
  1. 自定义组件
function Article({title,content,active}) {
  return (
    <div>
      <h2>{title}</h2>
      <p>{content}</p>
      <p>状态: {active ? '显示中' : '已隐藏'}</p>
    </div>
  )
}

export default function App() {
  return (
    <>
      <Article
        title="标题1"
        content="内容1"
        active 
      />
      <Article
        title="标题2"
        content="内容2"
         
      />
      <Article
        title="标题3"
        content="内容3"
        active 
      />
    </>
  )
}
  1. 配合jsx展开语法通过props进行数据传递
function Detail({content,active}) {
  return (
    <>
      <p>{content}</p>
      <p>状态: {active ? '显示中' : '已隐藏'}</p>
    </>
  )
}

function Article({ title, detailData }) {
  return (
    <div>
      <h2>{title}</h2>
      <Detail
        {...detailData}
      />
    </div>
  )
}

export default function App() {
  const articleData = {
    title: '标题',
    detailData: {
      content: '内容',
      active: true
    }
  }
  return (
    <>
      <Article
        {...articleData}
      />
    </>
  )
}
  1. 类vue插槽功能实现
function List({ children,title,footer = <p>默认底部</p> }) {
  return (
    <div>
      <h2>{title}</h2>
      <ul>
        {children}
      </ul>
      {footer}
    </div>
  )
}

export default function App() {
  return (
    <>
      <List
        title = '列表1'
        footer={<p>这是底部内容1</p>}
      >
        <li>内容1</li>
        <li>内容2</li>
        <li>内容3</li>
      </List>
      <List
        title = '列表2'
      >
        <li>内容a</li>
        <li>内容b</li>
        <li>内容c</li>
      </List>
    </>
  )
}
  1. 传值是单向的,不要尝试对数据做修改
  2. 子组件向父组件传值
import { useState } from "react";

function Detail({ onActive }) {
  let [counts,setCounts] = useState(0);
  function handleClick() {
    setCounts(++counts);
    onActive(counts);
  }
  return (
    <>
      <span>{counts}</span>
      <button onClick={handleClick}>点击+1</button>
    </>

  )
}

export default function App() {
  function handleActive(params) {
    console.log('params: ', params);
  }
  return (
    <>
      <Detail
        onActive={handleActive}
      />
    </>
  )
}
  1. 课程中提到的其他的知识点:section标签和h1标签嵌套时会出现字体从大到小的样式,html用于结构呈现,css用于样式处理,需要通过设置样式,避免出现意外;
  2. 使用Context深层传递参数以及在组件间复用相同的参数:
import { createContext, useContext, useState } from 'react';

// 创建一个主题的上下文
const ThemeContext = createContext();

function App() {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={theme}>
      <Header />
      <Content />
    </ThemeContext.Provider>
  );
}

function Header() {
  const theme = useContext(ThemeContext);

  return (
    <header style={{ background: theme === 'light' ? 'lightgray' : 'darkgray' }}>
      Header
    </header>
  );
}

function Content() {
  const theme = useContext(ThemeContext);

  return (
    <div style={{ background: theme === 'light' ? 'white' : 'black', color: theme === 'light' ? 'black' : 'white' }}>
      Content
    </div>
  );
}

export default App;