定制小程序开发React中的函数组件详解

1. 创建方式

 //  写法一const Hello = (props) => {          return <div>{props.message}</div>} //  写法二const Hello = props => <div>{props.message}</div>  // 写法三function Hello(props) {    return <div>{props.message}</div>}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2. 定制小程序开发函数组件代替类组件

定制小程序开发面临的问题

  • 定制小程序开发函数组件没有state => React v16.8.0推出Hooks API,其中的一个API叫做useState可以解决问题
  • 函数组件没有生命周期 => React v16.8.0推出Hooks API,其中的一个API叫做useEffect可以解决问题

我们对比一下两种组件实现 n + 1 的例子

类组件

class App extends React.Component {    constructor(props) {        super(props);        this.state = {            n: 0        }    }    addNum = () => {        this.setState({n: this.state.n + 1})    }    render() {        return (            <div className='App'>                <span>n:{this.state.n}</span>                <button onClick={this.addNum}>n+1</button>            </div>        )    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

函数组件

const App = props => {    const [n,setN] = React.useState(0)    function addNum(){        setN(n + 1)    }    return (        <div className='App'>            {n}            <button onClick={addNum}>+1</button>        </div>    )}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

相比之下函数组件更为简洁一些

使用 useEffect 解决生命周期问题

  1. 模拟 componentDidMount 首次渲染
useEffect(() => {     //  模拟componentDidMount  首次渲染        console.log('use effect')    },[])    // 空数组必须写
  • 1
  • 2
  • 3
  1. 模拟 componentDidUpdate
const [n, setN] = React.useState(0)useEffect(() => {     //  模拟  componentDidUpdate         console.log('n 变化了')    },[n])  // 数组里面可以写多个参数表示监听多个变量useEffect(() => {     //  模拟  componentDidUpdate         console.log('任意属性变更了')    })  // 不写数组表示监听所有 useState  的变量//  但是这样在第一次渲染时也会触发函数的执行   解决方法使用自定义Hook 见下一标题
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 模拟componentWillUnmount
  useEffect(() => {            return () => {            console.log('Child 销毁了')        }    })    //  返回一个函数 在销毁时执行
  • 1
  • 2
  • 3
  • 4
  • 5
  1. constructor
    函数组件执行的时候,就相当于constructor

  2. shouldComponentUpdate
    后面的 React.memo和useMemo可以解决

  3. render
    函数组件的返回值就是render的返回值.

//  模拟render里面写逻辑const X = (props) => {    console.log('我是要写的逻辑')    return (        <div>逻辑模拟</div>    )}const App = props => {    let [childVisible, setChildVisible] = useState(true)    const changeVisible = () => {        setChildVisible(!childVisible)    }    return (        <div className='App'>            {childVisible ? <button onClick={changeVisible}>{childVisible}</button> :                <button onClick={changeVisible}>hide</button>}            {/*{childVisible ? <Child/> : null}*/}            <Child/>            <X/>             </div>    )}   // 一个函数便是一个组件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3. 自定义 Hook 之 useUpdate
解决上面 n 值初次渲染就执行的问题

const App = props => {    const [n, setN] = useState(0)    const onClick = () => {        setN(n + 1)    }    const [nUpdateCount, setNUpdateCount] = useState(0)    useEffect(() => {    // 初次渲染就执行 + 1        setNUpdateCount(nUpdateCount + 1)    }, [n])    useEffect(() => {    // 初次渲染就执行 判断是否大于1         if(nUpdateCount > 1){            console.log('n变了')        }    },[nUpdateCount])    return (        <div className='App'>            n值变成了:{n}            <button onClick={onClick}>n+1</button>        </div>    )}//  通过使用两次 useEffect 第一个触发第二个 useEffect 函数计数,大于0便是n值变化了
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

上面的代码很乱 改进一下

const useX = (fn, dep) => {   // 这就是自定义 Hook 这就可以抽离成别的文件    const [count, setCount] = useState(0)    useEffect(() => {        setCount(x => x + 1)    }, [dep])    useEffect(() => {        if (count > 1) {            fn()        }    }, [count,fn])}const App = props => {    const [n, setN] = useState(0)    const onClick = () => {        setN(n + 1)    }    useX(() => {        console.log('n 变化了')    }, n)    return (        <div className='App'>            n值变成了:{n}            <button onClick={onClick}>n+1</button>        </div>    )}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发