每一周的学习报告 第八周 React组件入门

React组件

组件允许你将 UI 拆分为独立可复用的代码片段

React组件的分类

React 的组件可以定义为 class 或函数的形式
class式组件中有着更多的方法与属性

函数式组件

定义一个函数,使其返回一个虚拟DOM就是函数式组件了

    function NewComponent(){
      return <h1>Hello World</h1>;
    }

类式组件

定义class组件,想要继承一个内置的class:React.Component

    class Welcome extends React.Component {
    render() {
        return <h1>Hello, World</h1>;
    }
    }

render() 函数必须被定义,它的返回值与函数式组件一样,都是你想要显示到浏览器上的DOM

组件渲染到页面

我们可以通过书写HTML标签一样的方式将组件渲染到页面中

    ReactDOM.render(<Weather/>,document.getElementById('test'))

由于JSX的语法要求,组件的首字母必须大写

组件实例的三大属性

由于函数式组件没有组件实例,所以三大属性一般是class组件使用,但最新的hooks写法可以让函数式组件使用三大属性

state属性

state属性是组件实例上的一个对象,组件的state驱动着页面发生改变
换句话说,我们可以通过改变state属性使页面发生改变,也就是我们需要的交互

初始化state属性

我们可以在构造器constructor上初始化state属性

    constructor(props){
        super(props)
        this.state = {isHot:true} //初始化状态
    }

注意:state属性必须是一个对象

下面我们通过一个实例演示,怎么通过state属性改变页面
    class Weather extends React.Component{
        constructor(props){
            super(props)
            this.state = {isHot:true} //初始化状态
            this.changeWeather = this.changeWeather.bind(this)
        }
        render(){
            return <h1 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h1>
        }
        changeWeather() {
            const isHot = this.state.isHot
            this.setState({isHot:!isHot}) //取反赋回去
        }
    }
    //渲染组件到页面
    ReactDOM.render(<Weather/>,document.getElementById('test'))

在h1标签中绑定一个onClick时间,点击后调用changeWeather方法,改变isHot状态,页面重新渲染显示改变后的天气
更改state时,必须使用React的一个内置函数setState()进行修改,不可以直接对state进行修改
如上面的changeWeather()方法

    changeWeather() {
        const isHot = this.state.isHot
        this.state.isHot=!isHot //取反赋回去
        //这样写是错误的
    }

直接修改state中的isHot,将导致页面不能更新


类中方法this指向问题

类中方法的this指向实例自身,当onClick事件被触发后,是onClick帮我们调用方法,不是在实例中被调用,因此就会出现this的值是undefined
怎么解决这个问题,我们可以使用bind(this)给为事件处理函数绑定实例

    constructor(props){
        super(props)
        this.changeWeather = this.changeWeather.bind(this)
    }

这样处理后,事件触发后this能正确指向


不写constructor()

上面的代码其实不写constructor也是可以的

    class Weather extends React.Component{
        state = {isHot:true} //初始化状态
        render(){
            return <h1 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h1>
        }
        changeWeather= ()=> {
            const isHot = this.state.isHot
            this.setState({isHot:!isHot}) //取反赋回去
        }
    }
    //渲染组件到页面
    ReactDOM.render(<Weather/>,document.getElementById('test'))

在class中,直接添加一个state属性就可以完成对状态的初始化,this的指向问题也可以用箭头函数解决

props属性

props属性存了外部传入的数据,与state属性类似也是一个对象
怎么在外部传入数据

    //渲染组件到页面
    ReactDOM.render(<Weather wind = 9/>,document.getElementById('test'))

渲染组件到页面时,给组件标签添加的属性将作为一个对象传入到props属性中
注意:
props属性是无法在组件内部进行修改的,只能进行调用


给传入的props做限制与设立初始值
给props做限制,可以使用propTypes

    MyConponent.propTypes = {
        name:PropTypes.string.isRequired,
        age:PropTypes.number,
        sex:PropTypes.string
    }

给MyConponent类本身添加一个propTypes属性,给需要限制的props添加PropTypes.types属性,就可以限制类型
PropTypes.isRequired就是强制要求该类型
自 React v15.5 起,React.PropTypes 已移入另一个包中。需要 prop-types 库 代替
给props设立初始值,可以使用defaultProps

    MyConponent.defaultProps = {
        age:18
    }

属性对应的对象就是props的初始值


refs属性与事件处理

获取节点,原生JS提供了很多方法如,getElementById
React提供一个refs属性帮助我们获取到节点

  1. 字符串形式
    render(){
        return (
            <div>
                <input type="text" ref="input1"/>&nbsp;
                <button onClick={this.show}>点我提示左侧数据</button>&nbsp;
                <input type="text" ref="input2" onBlur={this.show2} placeholder="失去焦点提示数据"/>
            </div>
        )

给返回的元素添加一个ref属性,属性的值为一个字符串,则this.refs.字符串中会存有ref属性对应的DOM节点
2. 回调函数形式

   render(){
        return (
            <div>
                <input type="text" ref={c => this.input1 = c}/>&nbsp;
                <button onClick={this.show}>点我提示左侧数据</button>&nbsp;
                <input type="text" ref={c => this.input2 = c} onBlur={this.show2} placeholder="失去焦点提示数据"/>
            </div>
        )
    }

给ref属性中写入一个回调函数,此回调函数中的参数就是对应的DOM节点
3. creactRef形式

    class Demo extends React.Component{
        container = React.createRef()
        container2 = React.createRef()
        render(){
            return (
                <div>
                    <input type="text" ref={this.container} />&nbsp;
                    <button onClick={this.show}>点我提示左侧数据</button>&nbsp;
                    <input type="text" ref={this.container2} onBlur={this.show2} placeholder="失去焦点提示数据"/>
                </div>
            )
        }
        show = ()=>{
            alert(this.container.current.value)
        }

        show2 = ()=>{
            alert(this.container2.current.value)
        }

    }

组件的生命周期

组件的挂载(mount)与卸载(unmount)便是组件的整个生命周期
在下面这个案例,我们希望设立一个计时器让h1标签的透明度不断发生变化

			class Life extends React.Component{
				state = {opacity:1}
				render(){ 
                    setInterval(() => {
						//1.获取原来的opacity
						let {opacity} = this.state
						//2.递减
						opacity -= 0.1
						if(opacity <= 0) opacity = 1
						//3.赋回去
						this.setState({opacity})
					}, 200);
					const  {opacity} = this.state

					return (
						<div>
							<h1 style={{opacity}}>组件</h1>	
							<button onClick={this.death}>卸载组件</button>
						</div>
					)
				}
				death = ()=>{
					//卸载组件
					ReactDOM.unmountComponentAtNode(document.getElementById('test'))
				}
			}
			ReactDOM.render(<Life/>,document.getElementById('test'))

将计数器写在render()方法中,每进行一次setState render就调用一次导致计数器无限累加
我们只需要调用一次计数器,这时我们可以使用一些React内置的方法
componentDidMount()
在组件挂载完毕后会自动调用一次componentDidMount()方法

    componentDidMount(){
        this.timer = setInterval(()=>{
            let {opacity}=this.state;
            opacity-=0.001;
            if(opacity<=0){
                opacity=1
            }
            this.setState({opacity:opacity})
        },1)
    }

将计数器写在componentDidMount()方法中,组件挂载完毕后自动调用
componentWillUnmount()
如果我们直接将组件卸载的话,会出现一个严重的错误。组件已经被卸载了,计数器还在继续计数。因此,在组件将于被卸载时,将计数器停止
这时就用到了componentWillUnmount()方法

    componentWillUnmount(){
        clearInterval(this.timer)
    }

以上两个方法就是生命周期钩子函数,它可以在组件运行到特定阶段时被调用
下面是组件完整的生命周期流程图:
生命周期流程图

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值