react基础篇(二)

目录

组件三大核心属性

组件中的state(状态)

组件中的props

补充说明constructor构造器

组件中的refs


组件三大核心属性

组件中的state(状态)

注意:状态不可直接更改,要用setState去进行修改

状态在哪里,操作状态的方法就在哪里

  1. 借助构造器,初始化状态,读写状态
    // 创建类式组件,继承react中的component
    class Weather extends React.Component {
      constructor(props){
        // 有构造器必须有super,语法规定
        super(props)
        // state 需要一个对象来承接
        this.state = { isHot: true }
      }
      render(){
        const {isHot} = this.state
        return <h1>今天天气{this.state.isHot ? '炎热': '凉爽'}</h1>
      }
    }
    // 渲染到页面上
    ReactDOM.render(<Weather/>,document.getElementById('test'))

绑定点击事件

  • 绑定事件

注意:1. 绑定的onClick要用驼峰 2. 调用的函数要写成{demo} 不需要加括号

 <script type="text/babel">
    // 创建类式组件,继承react中的component
    class Weather extends React.Component {
      constructor(props){
        // 有构造器必须有super,语法规定
        super(props)
        // state 需要一个对象来承接
        this.state = { isHot: true }
      }
      render(){
        // 读取状态
        const { isHot } = this.state
        // 绑定事件时不能用demo() 的形式,否则会默认执行,相当于把demo的返回值赋值给onclick
        // return <h1 onClick={demo()}>今天天气{isHot ? '炎热': '凉爽'}</h1>
        return <h1 onClick={demo}>今天天气{isHot ? '炎热': '凉爽'}</h1>
      }
    }
    // 渲染到页面上
    ReactDOM.render(<Weather/>,document.getElementById('test'))

    // 绑定的点击事件
    function demo(){
      console.log('标题被点击了');
    }
  </script>
  • 点击改变事件

目的获取实例身上的isHot然后去改变值

问题:获取不到实例身上的this

解决1:利用that,重新赋值that,成功获取

弊端:结构错误,一般只有两大块,一块是创建组件,一块是渲染组件

解决2:把changeWeather放在组件里面

错误:刚开始编译不报错,但点击时报错,changeWeather里面的this是undefined

原因:changeWeather不是实例调用的,而是render里面调用的,这里的this.changeWeather相当于直接调用

注意:类中的函数开启了局部的严格模式,所以this不指向window而是undefined

 解决3:在实例身上添加changeWeather方法,changeWeather的来源是在原型链上

 成功点击改变值

  <script type="text/babel">
    // 创建类式组件,继承react中的component
    class Weather extends React.Component {
       // 构造器只调用了一次
      constructor(props){
        super(props)
        this.state = { isHot: true }
        // 把原型链上的changeWeather 赋值给实例上的changeWeather,从而在下面this.changeWeather可以在实例身上找到changeWeather
        // 重新把this指向实例
        this.changeWeather = this.changeWeather.bind(this)
      }
      // render函数调用了 1+n次,第一次是初始化,n是状态更新的次数
      render(){
        // 读取状态
        // 这里的this 指的是实例对象
        const { isHot } = this.state
        return <h1 onClick={this.changeWeather}>今天天气{isHot ? '炎热': '凉爽'}</h1>
      }
      // 绑定的点击事件
      // changeWeather 点几次调用几次
      changeWeather(){
        // changeWeather放在哪里?——Weather的原型对象上,供实例使用
        // 由于changeWeather是作为onClick的回调,所以不是实例调用的,是直接调用
        // 类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined
        // console.log(this);

        // 获取原来的isHot值
        const isHot = this.state.isHot
        this.setState({isHot: !isHot})

        // 严重注意: 状态(state)不可直接更改
        // this.state.isHot = !isHot 错误写法
      }
    }
    // 渲染到页面上
    ReactDOM.render(<Weather/>,document.getElementById('test'))
  </script>

state简写形式(开发常用)

注意:自定义函数需要写成赋值语句,且为箭头函数,否则会报错,找不到this

  <script type="text/babel">
    class Weather extends React.Component {
      // 不需要外面传进来的参数赋值,可以直接写,不需要写在构造器内
      state = {isHot: false, wind: '微风'}
      render(){
        const { isHot } = this.state
        return <h1 onClick={this.changeWeather}>今天天气{isHot ? '炎热': '凉爽'}</h1>
      }
      // 自定义方法——赋值语句
      // 使用箭头函数,箭头函数本身无this,向外找,此时this就是weather实例
      changeWeather = () => {
        const isHot = this.state.isHot
        this.setState({isHot: !isHot})
      }
    }
    // 渲染到页面上
    ReactDOM.render(<Weather/>,document.getElementById('test'))
  </script>

组件中的props

注意:props是只读的,不能修改,如:this.props.name = 'jack'

props的基本使用

  <script type="text/babel">
    // 创建实例
    class Person extends React.Component {
      render(){
        console.log('this:',this);
        const {name, age, sex} = this.props
        return (
          <ul>
            <li>姓名:{name}</li>
            <li>年龄:{age}</li>
            <li>性别:{sex}</li>  
          </ul>
        )
      }
    }
    // 渲染到页面上,数值型的age可以写成 age={18}
    ReactDOM.render(<Person name="li" age="18" sex="女"/>,document.getElementById('test'))
  </script>

 props的批量赋值

// 扩展运算符解构赋值
const p = {name: 'liu', age:'20', sex: '男'}
ReactDOM.render(<Person {...p}/>,document.getElementById('test2'))

标签限制(限制类型,必传,默认值)

注意:实例身上的propTypes中p是小写的,限制类型的PropTypes中的p是大写的

    // 限制类型
    Person.propTypes = {
      name: PropTypes.string.isRequired,  // isRequired必须传的值
      age: PropTypes.number,
      sex: PropTypes.string
    }

    // 设置默认值
    Person.defaultProps = {
      age: 18,
      sex: '男'
    }

一般写在定义实例的时候做限制

    // 创建实例
    class Person extends React.Component {
      render(){
        console.log('this:',this);
        const {name, age, sex} = this.props
        return (
          <ul>
            <li>姓名:{name}</li>
            <li>年龄:{age}</li>
            <li>性别:{sex}</li>  
          </ul>
        )
      }

      // 限制类型
      static propTypes = {
        name: PropTypes.string.isRequired,  // isRequired必须传的值
        age: PropTypes.number,
        sex: PropTypes.string
      }

      // 设置默认值
      static defaultProps = {
        age: 18,
        sex: '男'
      }
    }

补充说明constructor构造器

类中的构造器可以省略

constructor的作用:

  1. 对state的初始化,如:this.state = {isHot: true},但可以单独在构造器外面直接写 state = {isHot: true}
  2. 对事件的绑定,如:this.changeWeather = this.changeWeather.bind(this),但可以直接用箭头函数在构造器外面写
  3. 对于props,有传了props参数就必须要有super(props),否则props会是undefined。构造器是否接收props,是否传递给super,取决于:是否希望在构造器中通过this访问到props
constructor(props){
     super(props)
     console.log('constructor',this.props);
 }

 

constructor(props){
   super()
   console.log('constructor',this.props);
}

 

组件中的refs

简介:类似于vue中的ref,是标签的标识

refs:{key: value} key为绑定的ref值,value为所在的标签

注意:string类型的refs效率不高,在未来可能会被弃用

ref是字符串形式

 

 

 ref为回调函数类型

注意:内联函数(即上例)的ref第一次渲染的时候会调用一次,之后更新的时候会调用两次,更新中的第一次为清空上一次的节点内容,此时的currentNode为null,第二次的时候才是正式更新,但是具体的影响并不大

如需解决:使用类函数调用(但是无关紧要)

<input ref={this.logInput} type="text" placeholder="点击提示数据" />

logInput = (e) => {
   console.log('e',e);
 }

使用createRef创建ref(常用)

创建的ref是“专人专用”的

  <script type="text/babel">
    // 创建实例 
    class Demo extends React.Component{
      myRef = React.createRef()
      myRef2 = React.createRef()
      showData = ()=>{
        alert(this.myRef.current.value)
      }
      showData2 = ()=>{
        alert(this.myRef2.current.value)
      }
      render(){
        return(
          <div>
            <input ref={this.myRef} type="text" placeholder="点击提示数据" />&nbsp;
            <button onClick={this.showData}>点击提示左侧</button>&nbsp;
            <input ref={this.myRef2} type="text" onBlur={this.showData2} placeholder="失去焦点提示数据" />
          </div>
        )
      }
    }

    // 渲染到页面上
    ReactDOM.render(<Demo />,document.getElementById('test1'))
  </script>

注意:切勿过度使用ref,部分可以使用event.target获取节点信息

  <script type="text/babel">
    // 创建实例 
    class Demo extends React.Component{
      myRef = React.createRef()
      myRef2 = React.createRef()
      showData = ()=>{
        alert(this.myRef.current.value)
      }
      showData2 = (event)=>{
        alert(event.target.value)
      }
      render(){
        return(
          <div>
            <input ref={this.myRef} type="text" placeholder="点击提示数据" />&nbsp;
            <button onClick={this.showData}>点击提示左侧</button>&nbsp;
            <input type="text" onBlur={this.showData2} placeholder="失去焦点提示数据" />
          </div>
        )
      }
    }

    // 渲染到页面上
    ReactDOM.render(<Demo />,document.getElementById('test1'))
  </script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值