Skip to content

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 思路分析: **

  1. 将复用的状态和逻辑代码封装到一个组件中 (比如命名为 Position),
javascript
class Position extends React.Component{
    // 定义共享状态
    state = {...}

    // 根据具体需求逻辑定义共享逻辑代码,比如
    handle = e => {
    	this.setState({...})
    }
    render(){
        return this.props.render(this.state)
    }
}
  1. 在这个组件上添加一个 render 属性. render 属性的值是一个函数
javascript
<Position render={() => {}} />
  1. 把要真正渲染到页面的组件,当做箭头函数的返回值
javascript
<Position render={() => <Cat />} />
  1. 这个组件 render 的函数可以接收组件中的状态数据

    javascript
    <!-- <Position  render={ pos =><Cat {...pos}/>}/> -->
  2. 在 Position 中通过 this.props.render()得到真正要渲染的组件

javascript
//Position组件
render() {
    return this.props.render()
}
  1. 并在在调用 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 规则:

  1. 必须在函数组件/其他 hook 中使用.不能再类组件中使用 hook,也不能在普通函数中使用 hook
  2. hook 在使用的时候,必须在最顶级的作用域使用,而且一般要写在最上面

官方提供的 Hooks 介绍