React 组件通信-全面解析

父子组件通信

// 导入
import {
    
     useState } from "react";

import "./App.scss";
import {
    
     defaultTodos } from "./components/module/contentData";

// 子组件
const Module = ({
     
      id, done, text, onToggle, onDelData }) => {
    
    
  return (
    <div>
      <span className={
    
    done ? "" : "text"} onClick={
    
    () => onToggle(id)}>
        -- {
    
    text} --
      </span>
      {
    
    /* 点击后子组件调用父组件函数,将 id 回传给父组件 */}
      <button onClick={
    
    () => onDelData(id)}>删除</button>
    </div>
  );
};

// 父组件
const App = () => {
    
    
  // 状态
  const [defaultTodo, setDefaultTodo] = useState(defaultTodos);

  // 修改文字状态
  const onToggle = (id) => {
    
    
    setDefaultTodo(
      defaultTodo.map((item) => {
    
    
        if (item.id === id) return {
    
     ...item, done: !item.done };
        return item;
      })
    );
    console.log(defaultTodo);
  };

  // 删除
  const onDelData = (xId) => {
    
    
    const dataId = defaultTodo.filter((item) => item.id !== parseInt(xId));
    console.log(xId, "点击了删除", dataId);
    setDefaultTodo(dataId);
  };

  return (
    <div>
      <p>xxx </p>
      {
    
    defaultTodo.map((item) => {
    
    
        // key 可以直接用
        // return <Module key={item.id} done={item.done} text={item.text}></Module>;

        // {...item} 解构写法,简化开发
        // onToggle 给子组件调用的函数
        return (
          <Module
            key={
    
    item.id}
            {
    
    ...item}
            onToggle={
    
    onToggle}
            onDelData={
    
    onDelData}
          ></Module>
        );
      })}
    </div>
  );
};

export default App;

这段代码包括一个父组件App和一个子组件Module,实现了父子组件之间的通信。

在父组件App中,使用useState来定义了一个状态defaultTodo,并初始化为defaultTodosdefaultTodos是从./components/module/contentData文件中导入的一个默认的待办事项列表。

App组件中定义了两个回调函数onToggleonDelData,分别用于切换待办事项的状态和删除待办事项。

子组件Module接收父组件传递的参数iddonetextonToggleonDelData。在子组件中,使用这些参数来展示待办事项的内容和状态,并通过点击事件调用父组件传递的回调函数来修改状态或删除待办事项。

App组件中,通过defaultTodo.map遍历defaultTodo数组,并将每个待办事项的数据作为子组件Module的属性进行渲染。

父组件和子组件之间通过回调函数的方式进行通信,子组件通过调用父组件传递的回调函数来传递数据或状态的更新。同时,父组件通过useState来管理状态的变化,并通过调用setDefaultTodo函数来更新状态。

在CSS样式方面,通过import "./App.scss"导入了App.scss文件,并在子组件的span元素中通过条件渲染添加了不同的样式效果。

总的来说,这段代码演示了React中父子组件之间通过props和回调函数进行通信,实现待办事项列表的展示、状态切换和删除功能。

兄弟组件之间的传值

import {
    
     useState } from "react";
import "./App.scss";
import From from "./components/ContentData";
import List from "./components/TitleData";

// 利用转态提升来让兄弟组件之间可以传值
function App() {
    
    
  const [data, setData] = useState([
    {
    
     id: 1, name: "李白", age: 19 },
    {
    
     id: 2, name: "杜甫", age: 29 },
    {
    
     id: 3, name: "白居易", age: 30 },
  ]);

  const addListData = (newData) => {
    
    
    console.log("执行了");
    setData([...data, {
    
     id: Date.now(), name: newData, age: 119 }]);
  };

  return (
    <div>
      <From data={
    
    data}></From>
      <hr />
      <List addListData={
    
    addListData}></List>
    </div>
  );
}

export default App;

List 子组件代码:

import {
    
     List } from "antd";
const ListData = ({
     
      data }) => {
    
    
  return (
    <div>
      <List
        size="large"
        header={
    
    <div></div>}
        footer={
    
    <div></div>}
        bordered
        dataSource={
    
    data}
        renderItem={
    
    (item) => <List.Item>{
    
    item.name}</List.Item>}
      />
    </div>
  );
};

export default ListData;

From 子组件代码:


import {
    
     ProForm, ProFormText } from "@ant-design/pro-components";
import "./index.css";

const From = ({
     
      addListData }) => {
    
    
  return (
    <div className="box-form">
      <ProForm
        onFinish={
    
    async (values) => {
    
    
          console.log(values);
          addListData(values.name);
        }}
      >
        <ProFormText name="name" label="姓名" />
      </ProForm>
    </div>
  );
};

export default From;

这段代码包括一个父组件App和两个子组件FromList,实现了兄弟组件之间的值传递。

在父组件App中,使用useState定义了一个状态data,并初始化为一个包含三个对象的数组。父组件还定义了一个名为addListData的函数,用于向data数组中添加新的数据。

父组件通过将data状态和addListData函数作为props传递给子组件FromList。子组件From接收addListData函数,当ProForm表单中的值发生变化且提交表单时,调用addListData函数将新的值添加到父组件的data状态中。

子组件List接收data作为props,并使用Ant Design的List组件展示data中的数据。

父组件和子组件之间的值传递通过props来完成,父组件将状态和函数传递给子组件作为props,子组件通过调用父组件传递的函数来影响父组件的状态。

整个应用的目的是让用户通过From组件中的表单输入一条数据,然后通过List组件展示已经输入的数据。父组件App作为中介,在兄弟组件之间传递数据和函数。

子组件可以根据自己的功能和需要使用父组件传递的数据或函数来实现相应的功能,实现了兄弟组件之间的值传递和交互。

跨组件传值

import {
    
     createContext, useState } from "react";
import ContentData from "./components/ContentData";
import TitleData from "./components/TitleData";

export const ThemeContext = createContext();

const App = () => {
    
    
  const [color, setcolor] = useState("#bfc");
  // 无视组件层级关系,跨组件通信
  const editColor = (e) => {
    
    
    console.log("触发");
    setcolor(e);
  };
  return (
    <div>
      {
    
    /* 共享数据 */}
      <ThemeContext.Provider value={
    
    color}>
        <p>123</p>
        <ContentData></ContentData>
        <hr />
        <TitleData editColor={
    
    editColor}></TitleData>
      </ThemeContext.Provider>
    </div>
  );
};

export default App;

TitleData 子组件:

const TitleData = ({
     
      editColor }) => {
    
    
  const triggeredChange = (e) => {
    
    
    console.log(e.nativeEvent.srcElement.value);
    editColor(e.nativeEvent.srcElement.value);
  };
  return (
    <div className="box-form">
      子组件:<p>TitleData</p>
      <input type="color" onChange={
    
    (e) => triggeredChange(e)} />
    </div>
  );
};

export default TitleData;

ContentData 子组件:

import {
    
     useContext } from "react";
import GrandsonModule from "./components/grandsonModule";
import {
    
     ThemeContext } from "../../App";

const ContentData = ({
     
      data }) => {
    
    
  const theme = useContext(ThemeContext);

  return (
    <div>
      子组件:<p style={
    
    {
    
     color: theme }}>ContentData {
    
    theme}</p>
      <GrandsonModule></GrandsonModule>
    </div>
  );
};

export default ContentData;

GrandsonModule 是子孙组件:

GrandsonModule 是 ContentData 子组件的子组件

import {
    
     useContext } from "react";
import {
    
     ThemeContext } from "../../../App";
const GrandsonModule = () => {
    
    
  const theme = useContext(ThemeContext);

  return (
    <div>
      子孙组件:<p>GrandsonModule {
    
    theme}</p>
    </div>
  );
};

export default GrandsonModule;

这段代码它演示了如何使用上下文(Context)在跨组件之间共享数据。

App组件中,首先使用createContext函数创建了一个上下文对象ThemeContext。然后,使用useState来定义一个状态color,初始值为"#bfc"。通过setcolor函数来更新color的值。

editColor函数中,通过调用setcolor函数来更新color的值。该函数在子组件TitleData中被调用,用于更新父组件的状态。

return语句中,将需要共享的数据color放在<ThemeContext.Provider>中的value属性中。这样,ThemeContext.Provider包裹的所有组件都可以访问这个共享的数据。在这个例子中,子组件ContentDataTitleData可以访问color的值。

子组件ContentData使用useContext钩子来订阅ThemeContext上下文,并使用theme变量来获取共享的数据color的值。在return语句中,展示了包含theme值的一段文字。

子组件GrandsonModule也使用了useContext钩子来获取color的值,并展示了包含theme值的一段文字。

子组件TitleData接收父组件传递的editColor函数,并在输入框的onChange事件中调用editColor函数来更新父组件的状态

猜你喜欢

转载自blog.csdn.net/wbskb/article/details/131988918
今日推荐