1、函数组件和class组件为什么会被区分开 ?
- 概述部分 需要学习哪些东西
-
函数组件 为啥叫无状态组件 ?
-
函数组件 总结一下 ?
-
为什么 称之为 class 简化部分 (当然函数组件功能可扩展)
2、 React非受控组件 ?
- 在哪使用 ?
- 举个例子
import React, { Component } from "react";
class UpFiles extends Component {
constructor(props) {
super(props);
this.state = {};
this.fileInputRef = React.createRef();
}
alertName = () => {
const elem = this.fileInputRef.current;
alert(elem.files[0].name);
};
render() {
return (
<div>
<input type="file" ref={this.fileInputRef} />
<button onClick={this.alertName}>alert name</button>
</div>
);
}
}
export default UpFiles;
- 实现效果
- 非常nice 选择 文件可打印出 名字
3、React Portals 在哪使用 ?
- 怎么使用这个 传送门 ?
- 举个例子 说明这个情况
fixed 放在body第一层(root外层)
1、先常规来写 不使用 portals
PortalsDemo.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
class PortalsDemo extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div
style={{
position: "fixed",
left: "300px",
top: "300px",
width: "200px",
height: "200px",
backgroundColor: "pink",
}}
>
{this.props.children}
</div>
);
}
}
export default PortalsDemo;
-
index.jsfixed 内容区域 -
页面效果 在 root内
2、使用 portals 试试
import React, { Component } from "react";
import ReactDOM from "react-dom";
class PortalsDemo extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
// return (
// <div
// style={{
// position: "fixed",
// left: "300px",
// top: "300px",
// width: "200px",
// height: "200px",
// backgroundColor: "pink",
// }}
// >
// {this.props.children}
// </div>
// );
//使用 portals 放在body上 root外
return ReactDOM.createPortal(
<div
style={{
position: "fixed",
left: "300px",
top: "300px",
backgroundColor: "pink",
}}
>
{this.props.children}
</div>,
document.body
);
}
}
export default PortalsDemo;
- 查看当前页面结构
明显可以看到逃离了 id='root'
4、React Context ?
使用步骤
1、使用 React.createContext 创建context 并写默认值
2、使用 ThemeContext.Provider 包裹需要使用数据的子组件 并传值 value={this.state.theme}
3、函数组件使用 ThemeContext.Consumer 消费数据
4、class子组件 消费数据先定义 contextType 然后取值 this.context
5、完成多层级传递
- 层级展示
- 完整代码展示
import React, { Component } from "react";
//创建context 并传入默认值
const ThemeContext = React.createContext("light");
// 函数组件使用 ThemeContext.Consumer 消费数据
function ThemeLink(props) {
return (
<ThemeContext.Consumer>
{(value) => <p>link's theme is {value}</p>}
</ThemeContext.Consumer>
);
}
// class子组件 消费数据先定义 contextType 然后取值 this.context
class ThemeButton extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const theme = this.context;
return (
<div>
<p>button's theme is {theme}</p>
</div>
);
}
}
ThemeButton.contextType = ThemeContext;
function Tooolbar() {
return (
<div>
<ThemeButton />
<ThemeLink />
</div>
);
}
class Context extends Component {
constructor(props) {
super(props);
this.state = {
theme: "light",
};
}
changeTheme = () => {
this.setState({
theme: this.state.theme === "light" ? "dark" : "light",
});
};
render() {
return (
<ThemeContext.Provider value={this.state.theme}>
<Tooolbar />
<hr />
<button onClick={this.changeTheme}>change the theme</button>
</ThemeContext.Provider>
);
}
}
export default Context;
- 页面效果展示 点击按钮 theme变化
- 非常nice !