一、核心总结
1、向子组件传值
- 父组件中,在子元素上直接填写属性来传递数据给 子组件, 子组件里可以通过 props 拿到传递过来的数据
2、向父组件传值
- 子组件中触发 props 上的方法来给父组件传值
二、注意点
- 读取 props 可以使用解构,如 function Child({name, age}){...}
- props 可以指定默认值,如 function Child({name, age = 10}){...}
- 可以使用 <Child {...props} /> 语法来转发所有 props,但不要过度使用
<A><B /></A>这样嵌套的JSX,<B/>被视为<A>组件的 children 属性- 不能直接改变 props,需要交互可以使用 state 进行间接操作
三、代码示例
3.1、父组件向子组件传递数据和函数,子组件通过 props 接收并调用父组件传递的函数来更新父组件的数据,实现父子组件之间的双向数据传递。
// 父组件
import { useState } from "react";
import Child from "./child";
function Parent() {
const [arr1, setArr1] = useState([
{id: 1, name: '111'},
{id: 2, name: '222'},
{id: 3, name: '333'},
]);
const [arr2, setArr2] = useState([
{id: 1, name: 'aaa'},
{id: 2, name: 'bbb'},
{id: 3, name: 'ccc'},
]);
const [tab, setTab] = useState(1);
const changeTab = () => {
setTab(tab === 1 ? 2 : 1);
}
// 接收子组件传递的数据
const setArr = (newArr) => {
if (tab === 1) {
setArr1(newArr);
} else {
setArr2(newArr);
}
}
return (
<div className="parent-box">
<p>parent page</p>
<div onClick={changeTab} style={{ cursor: 'pointer', display: 'flex', gap: '10px', contentAlign: 'center', justifyContent: 'center' }}>
<div style={tab === 1 ? {color: '#f00', textDecoration: 'underline'} : {color: '#000'}}>Tab 1 Content</div>
<div style={tab === 2 ? {color: '#f00', textDecoration: 'underline'} : {color: '#000'}}>Tab 2 Content</div>
</div>
<div>
{/* 向子组件传递数据 */}
<Child arr1={arr1} arr2={arr2} tab={tab} setArr={setArr} />
</div>
</div>
);
}
export default Parent;
3.2、子组件通过 props 接收父组件传递的数据和函数,并在子组件内调用父组件传递的函数来更新父组件的数据,实现父子组件之间的双向数据传递。
// 子组件
import React from "react";
class Child extends React.Component {
constructor(props) {
super(props);
// 接收父组件的数据
this.state = {
arr1: props.arr1,
arr2: props.arr2
};
}
deleteItem = (id) => {
const _arr = this.props.tab === 1 ? [...this.state.arr1] : [...this.state.arr2];
const newArr = _arr.filter(item => item.id !== id);
this.setState({ [this.props.tab === 1 ? 'arr1' : 'arr2']: newArr });
this.props.setArr(newArr); // 向父组件传递数据
}
renderArr1 = () => {
return this.state.arr1.map((item, index) => (
<div key={item.id}>
<span>{item.name}</span>----
<button type="button" onClick={() => this.deleteItem(item.id)}>delete</button>
</div>
));
}
renderArr2 = () => {
return this.state.arr2.map((item) => (
<div key={item.id}>
<span>{item.name}</span>---
<button type="button" onClick={() => this.deleteItem(item.id)}>delete</button>
</div>
));
}
renderContent = () => {
return this.props.tab === 1 ? this.renderArr1() : this.renderArr2();
}
render() {
return(
<div >
<p>child</p>
<div>{this.renderContent()}</div>
</div>
)
}
}
export default Child;