亲宝软件园·资讯

展开

React函数组件

『荼』 人气:0

1. 创建方式

 //  写法一
const Hello = (props) => {      
    return <div>{props.message}</div>
}

 //  写法二
const Hello = props => <div>{props.message}</div>  

// 写法三
function Hello(props) {
    return <div>{props.message}</div>
}

2. 函数组件代替类组件

面临的问题

我们对比一下两种组件实现 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>
        )
    }
}

函数组件

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>
    )
}

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

使用 useEffect 解决生命周期问题

1.模拟 componentDidMount 首次渲染

useEffect(() => {     //  模拟componentDidMount  首次渲染
        console.log('use effect')
    },[])    // 空数组必须写

2.模拟 componentDidUpdate

const [n, setN] = React.useState(0)
useEffect(() => {     //  模拟  componentDidUpdate 
        console.log('n 变化了')
    },[n])  // 数组里面可以写多个参数表示监听多个变量

useEffect(() => {     //  模拟  componentDidUpdate 
        console.log('任意属性变更了')
    })  // 不写数组表示监听所有 useState  的变量
//  但是这样在第一次渲染时也会触发函数的执行  
 解决方法使用自定义Hook 见下一标题

3.模拟componentWillUnmount

  useEffect(() => {    
        return () => {
            console.log('Child 销毁了')
        }
    })    //  返回一个函数 在销毁时执行

4.constructor

函数组件执行的时候,就相当于constructor

5.shouldComponentUpdate

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

6.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>
    )
}   // 一个函数便是一个组件

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值变化了

上面的代码很乱 改进一下

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>
    )
}

补充:函数组件代替 class 组件

为什么要用函数组件代替 class 组件?别问,简单!相比类组件来说,函数组件确实要简单太多, 不妨看一个 +1 的例子:

class App extends React.Component {
	const App = props = > {
		constructor() {
			const[n, setN] = React.useState(0);
			super();
			const addN = () = > {
				this.state = {
					setN(n + 1);
					n: 0
				}
			};
			return (
			} < div > {
				n
			}
			addN = () = > { < button onClick = {
					addN
				} > +1 < /button></div >
					this.setState({
						n: this.state.n + 1
					});)
		};
	}
	render() {
		return ( < div className = "App" > {
			this.state.n
		} < button onClick = {
			this.addN
		} > +1 < /button>
      </div > ); //这是公共的渲染部分
	}
	const rootElement = document.getElementById("root");
}
ReactDOM.render( < App / > , rootElement);

通过上面的例子你可以看出,同样是实现 +1 的操作,类组件要比函数组件复杂的多,类组件不仅涉及到 extends、setState 等 API,还会涉及到 this 的使用,而且代码量还很多。反观函数组件就要清爽的多,所以在开发中推荐使用函数组件。

总结

加载全部内容

相关教程
猜你喜欢
用户评论