一、父传子
props说明
1、props是只读对象
根据单项数据流的要求,子组件只能读取props中的数据,不能进行修改
2、props可以传递任意数据
数字、字符串、布尔值、数组、对象、函数、JSX(就是一个模板)
import React from "react";
// 函数式子组件
function FSonComponent(props) {
// props是一个对象 里面存储着通过父组件传入的所有数据
// props也可解构
// const {ft, flist, obj, getfun, biaoqian} = props
return(
<div style={{border: '1px solid #111',margin: '10px'}}>
<div>函数子组件</div>
<div>父传递:{props.ft} </div>
// 解构后的用法
<div>父传递:{ft} </div>
{/* 数组 */}
<ul>父传递:
{props.flist.map((item) =>
<li key={item}>{item}</li>
)}
</ul>
{/* 对象 */}
<div>{props.obj.name} </div>
{/* 方法 */}
<button onClick={props.getfun}>触发父组件方法</button>
{/* JSX */}
{props.biaoqian}
</div>
)
}
// 类子组件
class LSonComponent extends React.Component{
render() {
return(
// 类组件必须通过this关键词 去获取这里的props是固定的
<div style={{border: '1px solid #111',margin: '10px'}}>
<div>类子组件</div>
<div>父传递:{this.props.lt} </div>
</div>
)
}
}
// 父组件
class App extends React.Component{
state = {
ftext: '函数数据',
ltext: '类数据',
fllist: [1,2,3,4,5],
obj: {
name: 'lili',
age: 12
}
}
getfun = () => {
console.log('父组件方法')
}
render() {
return (
<div className="App" style={{width: '30%',border: '2px solid #111'}}>
<div>父组件</div>
<FSonComponent
ft={this.state.ftext}
flist={this.state.fllist}
obj={this.state.obj}
getfun={this.getfun}
biaoqian={<p>父组件中的p标签</p>}
/>
<LSonComponent lt={this.state.ltext} />
</div>
);
}
}
export default App;
二、子传父
子传父:子组件调用父组件传过来的函数,并把想要传递的数据当成函数实参传入即可
import React from "react";
// 子组件
function FSonComponent(props) {
const stext = '子组件自定义数据'
function clickfun () {
props.getSon(stext)
}
return(
<div style={{border: '1px solid #111',margin: '10px'}}>
<div>函数子组件</div>
<button onClick={() => props.getSon('子组件数据')}>点击传递</button>
<button onClick={clickfun}>点击传递的方法</button>
</div>
)
}
// 父组件
class App extends React.Component{
state = {
list: [1,2,3,4,5],
}
getSon = (text) => {
console.log(text)
}
render() {
return (
<div className="App" style={{width: '30%',border: '2px solid #111'}}>
<div>父组件</div>
<FSonComponent
getSon={this.getSon}
/>
</div>
);
}
}
export default App;
三、兄弟组件通信
兄弟组件通信:BSonComponent组件先将数据通过子传父传递给App然后通过父传子传递给ASonComponent组件
import React from "react";
function ASonComponent(props) {
return(
<div style={{border: '1px solid #111',margin: '10px'}}>
<div>函数子组件A</div>
<p>{props.sendA}</p>
</div>
)
}
function BSonComponent(props) {
const stext = 'BSon组件数据'
function clickfun () {
props.getSonB(stext)
}
return(
<div style={{border: '1px solid #111',margin: '10px'}}>
<div>函数子组件B</div>
<button onClick={clickfun}>点击传递</button>
</div>
)
}
// 父组件
class App extends React.Component{
state={
sendA: '测试兄弟通信'
}
getSonB = (text) => {
this.setState({
sendA: text
})
}
render() {
return (
<div className="App" style={{width: '30%',border: '2px solid #111'}}>
<div>父组件</div>
<ASonComponent
sendA={this.state.sendA}
/>
<BSonComponent
getSonB={this.getSonB}
/>
</div>
);
}
}
export default App;
四、跨组件通信
跨组件通信步骤:
1.创建Context对象 导出Provider(提供者)和Consumer(消费者)对象
2.使用Provider包裹根组件提供数据
3.需要用到数据的组件使用Consumer包裹获取数据
import React, {createContext} from "react";
// 1.导入createContext方法并解构Provider和Consumer
const {Provider, Consumer} = createContext()
function ASonComponent(props) {
return(
<div style={{border: '1px solid #111',margin: '10px'}}>
<div>函数子组件A</div>
<CSonComponent/>
</div>
)
}
function CSonComponent(props) {
return(
<div style={{border: '1px solid #111',margin: '10px'}}>
<div>函数子组件B</div>
{/* 3.通过Consumer使用数据 */}
<Consumer>
{value => <div>{value}</div>}
</Consumer>
</div>
)
}
// 父组件
class App extends React.Component{
state={
sendA: '跨组件通信'
}
render() {
return (
// 使用Provider包裹根组件
<Provider value={this.state.sendA}>
<div className="App" style={{width: '30%',border: '2px solid #111'}}>
<div>父组件</div>
<ASonComponent/>
</div>
</Provider>
);
}
}
export default App;
注意事项:
1.上层组件和层组件关系是相对的只要存在就可以使用 通常我们可以通过app作为数据提供方
2.这层涉及到的语法都是固定的 有两处,提供的位置用value提供数据 获取数据的位置{value => 使用value做什么都可以}