传送门:
React教程(一):React基础
React教程(二):React组件基础
组件是独立且封闭的单元,默认情况下组件只能使用自己的数据。(state)
组件化开发的过程中,完整的功能会拆分对个组件,在这个过程中不可避免的需要互相传递一些数据。
为了让各组件之间可以进行互相沟通,数据传递,这个过程就是组件通信。
组件通信方式可以归纳为以下几种情况:
代码演示:
// 类组件
class HelloWorld extends React.Component {
render() {
console.log("传递过来的值:", this.props);
return <div>{this.props.message}</div>;
}
}
class App extends React.Component {
// 1.父组件准备好需要传递的信息
state = {
msg: "父组件需要传递的信息",
};
render() {
return (
<div>
{/* 2.使用子组件时候,将父组件state中的信息添加到子组件标签的属性上,属性名可自定义 */}
<HelloWorld message={this.state.msg} />
</div>
);
}
}
// 函数组件
// 3.子组件通过props接收并
// 当然也可以在函数的形参中直接解构 const HelloWorld = ({message}) =>{}
const HelloWorld = (props) => {
//解构出父组件传递过来的信息
const { message } = props;
// 使用message
return <div>{message}</div>;
};
function App() {
// 1.准备好需要传递的信息
const msg = "父组件需要传递的信息";
return (
<div>
{/* 2.挂载到子组件的标签属性上 */}
<HelloWorld message={msg} />
</div>
);
}
this.props = xxxx // 这种写法达咩
函数
、JSX
// 类组件
class HelloWorld extends React.Component {
render() {
console.log("props===", this.props);
return <div>{this.props.message}</div>;
}
}
function App() {
const msg = "父组件需要传递的信息";
return (
<div>
<HelloWorld
message={msg}
flag={true}
ui={<div>我是jsx元素</div>}
person={{
name: "icy",
age: 23,
}}
list={[1, 23, 4, 5, 5]}
handle={() => {
console.log("我是函数");
}}
/>
</div>
);
}
关于props.children,可以获取子组件标签包裹着的内容。
示例:
// 类组件
class HelloWorld extends React.Component {
render() {
console.log("props===", this.props);
return <div>{this.props.children}</div>;
}
}
// // 3.子组件通过props接收并
// // 当然也可以在函数的形参中直接解构 const HelloWorld = ({message}) =>{}
// const HelloWorld = (props) => {
// //解构出父组件传递过来的信息
// const { message } = props;
// // 使用message
// return {message};
// };
function App() {
const msg = "父组件需要传递的信息";
return (
<div>
<HelloWorld>
<span>我是被子组件包裹的内容</span>
</HelloWorld>
</div>
);
}
如果想使用子组件包裹着的内容,只能这样使用,否则包裹的内容会被忽略,不会渲染到页面中。
原理:子组件调用父组件传递过来的函数,将想要传递的数据当成函数的实参传入即可
。
代码说明:
const Son = (props) => {
// 3.子组件接收该回调函数
const { getDataFun } = props;
// 4. 子组件准备好需要传递给父组件的数据
const msg = "我是来自子组件的数据";
// 5.调用回调函数,将数据作为实参传入
getDataFun(msg);
return <div>我是子组件</div>;
};
function App() {
// 1.父组件准备一个回调函数
const getDataFromSon = (data) => {
// 6.获得子组件传递过来的数据并使用
console.log("data===", data);
};
return (
<div>
{/* 2.将函数传递给子组件 */}
<Son getDataFun={getDataFromSon} />
</div>
);
}
我们可以看到打印出来的结果,来验证传递有无成功。
此外,该函数调用了即可传递无论它是在哪里被调用的。
举个例子:
const Son = (props) => {
// 3.子组件接收该回调函数
const { getDataFun } = props;
// 4. 子组件准备好需要传递给父组件的数据
const dealFunc = () => {
const msg = "我是来自子组件的数据";
// 5.调用回调函数,将数据作为实参传入
getDataFun(msg);
};
return <div onClick={dealFunc}>我是子组件</div>;
};
即使它放在div的电机事件dealFunc中执行,那么点击div时那他还是算执行了getDataFun,数据一样会被传递到父组件中。
原理:通过状态提升机制,利用共同的父组件实现兄弟通信
1.先把子组件2中的数据传递给父组件
2.再把父组件中收到的数据保存下来,传给子组件1
从而实现了组件2 - > 组件1
代码基本实现:
// 子组件1
const Son1 = (props) => {
// 4.准备一个需要传递给son2的数据
const son1Data = "我是来自son1的数据";
// 5.接受父组件传递过来的回调函数
const { getDataFromSon1 } = props;
return (
<button
onClick={() => {
// 6.将数据传递给父组件app
getDataFromSon1(son1Data);
}}
>
我是son1,点我数据会传给son2
</button>
);
};
// 子组件2
const Son2 = (props) => {
// 8.接受从父组件传递过来的son1数据
const { son1Data } = props;
return <div>这里son2组件,son1传递过来的数据是:{son1Data}</div>;
};
// 父组件
class App extends React.Component {
// 1.准备一个状态存储来自son1的数据
state = {
son1Data: "", // 初始值为空字符
};
// 2.准备一个回调函数,接收来自son1的数据
getDataFromSon1 = (data) => {
this.setState({
...this.state,
son1Data: data,
});
};
render() {
return (
<div>
{/* 3.传递回调函数 */}
<Son1 getDataFromSon1={this.getDataFromSon1} />
{/* 7.将从son1组件接收到的数据传给son2组件 */}
<Son2 son1Data={this.state.son1Data} />
</div>
);
}
}
上面是一个react形成的嵌套树,如果我们想从APP组件向一个下层任意组件传递数据,目前我们能采取的方式是一层一层的props往下传,显然这很繁琐。
所以,Context提供了一个无需为每层组件手动添加props,就能在组件树之间进行数据传递的方法。
实现步骤:
1.创建Context对象,导出Provider和Consumer对象
const { Provider, Consumer } = createContext;
<Provider value={this.state.msg}>
<SonA />
</Provider>
<Consumer>{(value) => <span>拿到的数据是:{value}</span>}
完整代码如下:
// 引入react核心包
import React, { createContext } from "react";
const { Provider, Consumer } = createContext();
// 子组件1
const SonA = () => {
return (
<div>
这里是组件A
<SonB />
</div>
);
};
// 子组件B
const SonB = () => {
return (
<div>
这里是组件B
<SonC />
</div>
);
};
// 子组件C
const SonC = (props) => {
return (
<div>
这里是组件C
{/* 使用Consumer包裹需要使用数据的组件,并且使用回调函数的方式使用数据 */}
<Consumer>{(value) => <span>拿到的数据是:{value}</span>}</Consumer>
</div>
);
};
// 根组件
class App extends React.Component {
state = {
msg: "11111好耶111",
};
render() {
return (
// 使用provider包裹根组件并提供数据
<Provider value={this.state.msg}>
<div>
<SonA />
</div>
</Provider>
);
}
}
export default App;
谷歌商店下载链接:https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
(访问不了的可以挂梯子,懂的都懂。)
如果实在没有的话,可以去极简插件
下载:
下载地址:https://chrome.zzzmh.cn/info/fmkadmapgofadopljbjfkapdkoienihi
这个插件的好处是可以监听你的react构建的页面,用过dev-tools的应该都知道怎么用。
然后就可以看到react组件的层级结构了,非常的nice: