函数式组件化开发

4/26/2024 react

# 函数式组件化开发

  • 子组件的创建及使用 1创2导3使用4传值
  • 父传子
  • 子传父
  • 插槽
    • 匿名插槽
    • 具名插槽
  • 单向数据流概念 实现方案
  • 父传子 数据类型限制

# 1.父传子 - 单向数据流

父组件 通过动态属性 或 静态属性 直接传递数据

子组件 通过 函数的形参 props 进行参数的接收

  • 父组件
<Child title="我是爸爸组件传递的字符串"  num={num} ></Child>
1
  • 子组件
export default function Child(props) {
    console.log(props);
    // 对象的解构
    const {title,num} = props;
    
    const setNewNum = ()=>{
        props.num = 2000   //报错:该属性 只读
    }
  return (
    <div>
        <h1>{props.title}</h1>
        <h2>{props.num}</h2>
        <h3>{title}</h3>
        <h4>{num}</h4>
        <button onClick={setNewNum}>修改数字</button>
        我是子组件
    </div>
  )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 单向数据流

表现: 父组件传递给子组件的数据 不可被 子组件修改 删除对象属性 删除数组的元素,子组件只能读取数据 显示

原因: 为了确保父组件内部数据 安全性(不被其他组件所影响)

# 2.子传父

回调函数

父组件传递一个 函数体 fn 给 子组件

子组件在需要修改数据的地方,调用这个 函数体 fn 相当于 间接调用了父组件里面的方法 fn, 可以在fn中 对父组件的数据进行更新

  • 父组件
export default function Father(){
    
    const  [title,setTiTle] = useState('老数据')
    
    const fn = (data)=>{
        setTiTle(data)
    }
    
    
    return (
    	<>
           <Child title={title}  fn={fn} > </Child>
		</>
    )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  • 子组件

export default function Child(props){
    
    const {title,fn} = props
    
    const setTitle = ()=>{
        //需要告诉父组件 我正在改title 并传递数据给父组件
        fn('这是修改之后的标题')
    }
    
    
    return (
        <div>
            <h1> {title}</h1>
            <button onClick={setTitle}>点击修改 </button>
        </div>
    	
    )
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • 计数器案例

父组件

import React, { useState } from "react";

import Num from "./components/Num";
export default function App() {
  const [total, setTotal] = useState(1);

  const updateTotle = (newTotal) => {
    setTotal(newTotal);
  };
  const updateTotle1 = (newTotal) => {
    setTotal(newTotal);
  };
  return (
    <div>
      <Num
        total={total}
        updateTotle1={updateTotle1}
        updateTotle={updateTotle}
      ></Num>
    </div>
  );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

子组件

import React from "react";
import "./index.css";
export default function Num(props) {
  let { total, updateTotle, updateTotle1 } = props;

  const addBtn = () => {
    //不能直接需改父组件传递过来的数据
    // 将最新数据 传递给父组件 让父组件修改数据
    // 调用父组件传递过来的函数,通过这个函数去修改父组件的数据
    updateTotle(total + 1);
  };
  const reduceBtn = () => {
    updateTotle1(total - 1);
  };
  return (
    <div className="num-box">
      <button onClick={reduceBtn}>-</button>
      <span>{total}</span>
      <button onClick={addBtn}>+</button>
    </div>
  );
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

简化版

父组件

import React, { useState } from "react";

import Num from "./components/Num";
export default function App() {
  const [total, setTotal] = useState(1);
  return (
    <div>
      <Num
        total={total}
        updateTotle={val=>setTotal(val)}
      ></Num>
    </div>
  );
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

子组件

import React from "react";
import "./index.css";
export default function Num(props) {
  let { total, updateTotle } = props;
  return (
    <div className="num-box">
      <button onClick={()=>updateTotle(total - 1)}>-</button>
      <span>{total}</span>
      <button onClick={()=> updateTotle(total + 1)}>+</button>
    </div>
  );
}

1
2
3
4
5
6
7
8
9
10
11
12
13