render props
**render props 的作用: **提供共享的状态逻辑
**render props 是什么: **指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术
简单理解: 实现多个组件状态和逻辑共享的技术(复用)
javascript
export default class App extends Component {
render() {
return (
<div>
// 原来直接在这里渲染Cat和Mouse组件 // 使用了render props技术之后,
在这里使用封装了共享状态逻辑的组件, //
真正要渲染的Cat和Mouse需要当做render这个prop的返回值传进去
{/* <Position render={pos => <Cat {...pos} />}></Position> */}
{/* <Position render={pos => <Mouse {...pos} />}></Position> */}
</div>
);
}
}
**render props 思路分析: **
- 将复用的状态和逻辑代码封装到一个组件中 (比如命名为 Position),
javascript
class Position extends React.Component{
// 定义共享状态
state = {...}
// 根据具体需求逻辑定义共享逻辑代码,比如
handle = e => {
this.setState({...})
}
render(){
return this.props.render(this.state)
}
}
- 在这个组件上添加一个 render 属性. render 属性的值是一个函数
javascript
<Position render={() => {}} />
- 把要真正渲染到页面的组件,当做箭头函数的返回值
javascript
<Position render={() => <Cat />} />
这个组件 render 的函数可以接收组件中的状态数据
javascript<!-- <Position render={ pos =><Cat {...pos}/>}/> -->
在 Position 中通过 this.props.render()得到真正要渲染的组件
javascript
//Position组件
render() {
return this.props.render()
}
- 并在在调用 this.props.render 的时候,将 Position 组件中的数据,传递给 render 属性指向的函数
javascript
//Position组件
render() {
return this.props.render({...this.state})
}
//App组件
// pos接收Position中传递过来的数据,然后再传递给Cat组件
// <Position render={pos => <Cat {...pos} />}></Position>
Hooks
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
Hook 也叫钩子,本质就是函数,能让你使用 React 组件的状态和生命周期函数...
Hook 还没有完全替代 class,但是未来会逐步替代
为什么有 Hook?
组件复用状态逻辑比较难 (HOC 和 render props 写起来比较麻烦),Hook 使你在无需修改组件结构的情况下复用状态逻辑
解决了 this 难以理解的问题
希望可以逐渐取代 class
useState()基本使用
可以在单个组件中,多次使用
javascript
//导入 useState
import React, { useState } from "react";
function Example() {
// 1. 声明一个叫 "count" 的 state 变量
// 2. setCount 是用来操作count的方法
// 3. useState的值表示count的初始化值
// 4. 在后续的重新渲染中,useState 返回的第一个值将始终是更新后最新的 state
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
// 等价于
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
js
//setXXX 另外一种写法:
setXXX((data) => {
return data + 1;
});
useEffect() 基本使用
可以在单个组件中多次使用
这个 Hook,相当于 componentDidMount, componentDidUpdate 和 componentWillUnmount 的组合
javascript
//先导入
import React, { useState, useEffect } from "react";
function Example(props) {
const [count, setCount] = useState(0);
// 相当于 componentDidMount 和 componentDidUpdate
useEffect(() => {
document.title = `You clicked ${count} times`;
// 相当于componentWillUnmount
return () => {
// 完成一些清除工作...
};
// 如果在useEffect的第二个参数,传入一个空的数组,则useEffect只相当于componentDidMount
// 数组中可以传入state或porps数据,传入到数组的数据,就是被监听的数据,只要这些数据中有一个的值发生变化,这个函数才会重新执行
}, [count, props.name]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
Hook 规则:
- 必须在函数组件/其他 hook 中使用.不能再类组件中使用 hook,也不能在普通函数中使用 hook
- hook 在使用的时候,必须在最顶级的作用域使用,而且一般要写在最上面