React学习笔记【3】(react组件实例三大属性 state props ref)

学习地址:https://www.bilibili.com/video/BV1wy4y1D7JT
官方文档:

组件实例三大属性之一:state
理解:

  1. state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合)。
  2. 组件被称为‘状态机’,通过更新组件的state来更新对应的页面显示(重新渲染组件)。

注意事项:

  1. 组件中render方法中的this为组件实例对象。
  2. 组件自定义方法中的this为undefined,解决方法:
    a.强制绑定this,通过函数对象的bind();
    b.使用箭头函数形式。
  3. 状态数据不能直接修改或更新。setState();
<script type="text/babel">
	class MyComponent extends React.Component{
		constructor(prop){
			super(prop);
			this.state = {isHot:true};
			//解决changeHot中this指向问题
			this.changeHot = this.changeHot.band(this);
		};
		renter(){
			return <h1 onClick={this.changeHot}>今天的天气很{this.isHot ? '炎热' : '寒冷'}</h1>
		};
		changeHot(){
			//类中的方法默认开启严格模式所以changeHot中的this为undefined
			console.log(this);
			const isHot = this.state.isHot;
			//状态(state)必须通过setState更新
			this.setState({isHot:!isHot});
		};
	}
	//渲染组件
	ReactDOM.render(<MyComponent/>,document.getElementById('test'));
</script>

精简写法

<script type="text/babel">
	class MyComponent extends React.Component{
		state = {isHot:true};
		renter(){
			return <h1 onClick={this.changeHot}>今天的天气很{this.isHot ? '炎热' : '寒冷'}</h1>
		};
		//自定义方法使用赋值语句+箭头函数的形式
		changeHot = ()=>{
			const isHot = this.state.isHot;
			//状态(state)必须通过setState更新
			this.setState({isHot:!isHot});
		}
	}
</script>

组件三大属性之二:props
理解:

  1. 每个组件对象都会有props(properties的简写)属性。
  2. 组件标签的所有属性都保存在props中

作用

  1. 通过标签属性从组件外向组件内传递变化参数。
  2. 注意:组件内部不要修改props数据

编码操作

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="test"></div>
    <div id="test1"></div>
    <div id="test2"></div>

    <!-- react核心库 -->
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <!-- react-dom用于支持react操作dom -->
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <!-- 引入babel 用于将jsx转成js -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.js"></script>
    <!-- 引入prop-types 用于对标签属性进行限制 -->
    <script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>
    <script type="text/babel">
        class MyComponent extends React.Component {
            constructor(props) {
                // 构造器中是否接收props、是否传递给super,取决于是否希望在构造器中通过this访问props
                super(props);
                console.log('constructor', this.props);
            }
            // static 对类本身添加属性
            // 对标签属性进行类型、必要性的限制
            static propTypes = {
                name: PropTypes.string.isRequired,//限制 name必传且为字符串
                sex: PropTypes.string,//限制sex为字符串
                age: PropTypes.number,//限制age为数字
                // speak: PropTypes.func //限制speak为函数
            }
            // 指定默认标签属性值
            static defaultProps = {
                sex: '女',
                age: 18
            }
            render() {
                const { name, age, sex } = this.props;
                return (
                    <ul>
                        <li>姓名:{name}</li>
                        <li>性别:{sex}</li>
                        <li>年龄:{age + 1}</li>
                    </ul>
                )
            }
        };
        // 对标签属性进行类型、必要性的限制
        // MyComponent.propTypes = {
        //     name:PropTypes.string.isRequired,//限制 name必传且为字符串
        //     sex:PropTypes.string,//限制sex为字符串
        //     age:PropTypes.number,//限制age为数字
        //     speak:PropTypes.func //限制speak为函数
        // }
        // 指定默认标签属性值
        // MyComponent.defaultProps ={
        //     sex:'女',
        //     age:18
        // }
        ReactDOM.render(<MyComponent name="赵小黑" sex="男" age={18} />, document.getElementById('test'));
        const p = { name: '赵', sex: '男', age: 23 }
        ReactDOM.render(<MyComponent {...p} />, document.getElementById('test1'));


        // 函数式组件使用props
        function Person(props) {
            const { name, age, sex } = props;
            return (
                <ul>
                    <li>姓名:{name}</li>
                    <li>性别:{sex}</li>
                    <li>年龄:{age + 1}</li>
                </ul>
            )
        }
        // 对标签属性进行类型、必要性的限制
        // Person.propTypes = {
        //     name:PropTypes.string.isRequired,//限制 name必传且为字符串
        //     sex:PropTypes.string,//限制sex为字符串
        //     age:PropTypes.number,//限制age为数字
        //     speak:PropTypes.func //限制speak为函数
        // }
        // // 指定默认标签属性值
        // Person.defaultProps ={
        //     sex:'女',
        //     age:18
        // }
        ReactDOM.render(<Person name="赵大白" sex="女" age={18} />, document.getElementById('test2'));
    </script>
</body>

</html>

组件三大属性之三ref

  1. 字符串形式 的ref(官网已不推荐使用)
<script type="text/babel">
    // 创建组件
    class MyComponent extends React.Component{
        render(){
            return(
                <div>
                    <input ref="clickInput" type="text" placeholder="按钮触发" />&nbsp;
                    <button onClick={this.handleClick}>点击触发左侧</button>&nbsp;
                    <input ref="blurInput" onBlur={this.handleBlur} type="text" placeholder="失去焦点触发" />    
                </div>
            )
        };
        //按钮点击事件
        handleClick = ()=>{
            alert(`提示数据:${this.refs.clickInput.value}`)
        };
        //失去焦点事件
        handleBlur = ()=>{
            alert(`提示数据:${this.refs.blurInput.value}`)
        }
    };
    //渲染页面
    ReactDOM.render(<MyComponent />,document.getElementById('test'));
</script>
  1. 回调函数形式的ref
<script type="text/babel">
    // 创建组件
    class MyComponent extends React.Component{
        render(){
        	//内联形式定义
            return(
                <div>
                    <input ref={(currentNode)=>{this.clickInput = currentNode}} type="text" placeholder="按钮触发" />&nbsp;
                    <button onClick={this.handleClick}>点击触发左侧</button>&nbsp;
                    <input ref={currentNode => this.blurInput = currentNode} onBlur={this.handleBlur} type="text" placeholder="失去焦点触发" />    
                </div>
            )
        };
        // 按钮点击事件
        handleClick = ()=>{
            alert(`提示数据:${this.clickInput.value}`)
        };
        // 失去焦点事件
        handleBlur = ()=>{
            alert(`提示数据:${this.blurInput.value}`)
        }
    };
    // 渲染页面
    ReactDOM.render(<MyComponent />,document.getElementById('test'));
</script>

如果ref回调函数是以内联函数的方式定义的,在更新过程中会被执行两次,第一次传入参数null,然后第二次会传入参数DOM元素。这是因为在每次渲染时会创建一个新的函数实例,所以React清空就得ref并且设置新的,通过将ref的回调函数定义成class的绑定函数的方式可以避免上述问题。

  1. React.createRef 形式的ref
    React.createRef调用后可以返回一个容器,该容器可储存被ref所标识的节点该容器是‘专人专用’。
<script type="text/babel">
    // React.reateRef形式
    // 创建组件
    class MyComponent extends React.Component {
    	//React.createRef调用后可以返回一个容器,该容器可储存被ref所标识的节点该容器是‘专人专用’。
        input1 = React.createRef();
        input2 = React.createRef();
        // 按钮点击事件
        handleClick = () => {
            alert(`提示数据:${this.input1.current.value}`)
        }
        // 失去焦点事件
        handleBlur = () => {
            alert(`提示数据:${this.input2.current.value}`)
        }
        render() {
            return (
                <div>
                    <input ref={this.input1} type="text" placeholder="按钮触发" />&nbsp;
                    <button onClick={this.handleClick}>点击触发左侧</button>&nbsp;
                    <input ref={this.input2} onBlur={this.handleBlur} type="text" placeholder="失去焦点触发" />
                </div>
             )
        }
    }
    // 渲染页面
    ReactDOM.render(<MyComponent />, document.getElementById('test'));
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值