// 导入
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 ;
// {...item} 解构写法,简化开发
// onToggle 给子组件调用的函数
return (
<Module
key={item.id}
{...item}
onToggle={onToggle}
onDelData={onDelData}
></Module>
);
})}
</div>
);
};
export default App;
这段代码包括一个父组件App
和一个子组件Module
,实现了父子组件之间的通信。
在父组件App
中,使用useState
来定义了一个状态defaultTodo
,并初始化为defaultTodos
。defaultTodos
是从./components/module/contentData
文件中导入的一个默认的待办事项列表。
App
组件中定义了两个回调函数onToggle
和onDelData
,分别用于切换待办事项的状态和删除待办事项。
子组件Module
接收父组件传递的参数id
、done
、text
、onToggle
和onDelData
。在子组件中,使用这些参数来展示待办事项的内容和状态,并通过点击事件调用父组件传递的回调函数来修改状态或删除待办事项。
在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
和两个子组件From
和List
,实现了兄弟组件之间的值传递。
在父组件App
中,使用useState
定义了一个状态data
,并初始化为一个包含三个对象的数组。父组件还定义了一个名为addListData
的函数,用于向data
数组中添加新的数据。
父组件通过将data
状态和addListData
函数作为props传递给子组件From
和List
。子组件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
放在
中的value
属性中。这样,ThemeContext.Provider
包裹的所有组件都可以访问这个共享的数据。在这个例子中,子组件ContentData
和TitleData
可以访问color
的值。
子组件ContentData
使用useContext
钩子来订阅ThemeContext
上下文,并使用theme
变量来获取共享的数据color
的值。在return
语句中,展示了包含theme
值的一段文字。
子组件GrandsonModule
也使用了useContext
钩子来获取color
的值,并展示了包含theme
值的一段文字。
子组件TitleData
接收父组件传递的editColor
函数,并在输入框的onChange
事件中调用editColor
函数来更新父组件的状态