React--》React组件的三大核心属性

时间:2023-01-15 20:54:30

目录

state

事件绑定

props

函数式组件使用props

refs


state

state是组件对象最重要的属性,值是对象(可以包含多个 key-value的组合);组件被称为“状态机”,通过更新组件来对应页面显示(重新渲染组件),也就是有状态组件:

React--》React组件的三大核心属性

事件绑定

在React中进行事件绑定来渲染数据通过使用以下方式进行:

<body>
  <div id="root"></div>
  <!-- 引入react核心库 -->
  <script src="./node_modules/react/umd/react.development.js"></script>
  <!-- 引入react-dom,用于支持react操作dom -->
  <script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
  <!-- 引入babel,用于将jsx转为js -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">
    // 创建组件
    class Weather extends React.Component {
      constructor(props){
        super(props)
        this.state = {isHot:true,wind:'微风'}
        // 将changeWeather的this指向Weather的实例对象上
        this.changeWeather = this.changeWeather.bind(this)
      }

      render(){
        // 读取状态
        const {isHot,wind} = this.state
        return (
          <div>
            <h1>今天天气很{isHot ? '炎热' : '寒冷'},{wind}</h1>
            <button onClick={this.changeWeather}>点击切换天气</button>  
          </div>
        )
      }
      changeWeather(){
        // 获取原来的isHot的值
        const isHot = this.state.isHot
        // 注意:状态必须通过 setState 进行更新,且更新是一种合并不是替换
        this.setState({isHot:!isHot})

        // 禁止直接对state状态进行修改
        // this.state.isHot = !isHot 这种写法是错误的
      }
    }
    // 渲染页面到组件
    ReactDOM.render(<Weather/>,document.getElementById('root'))
  </script>
</body>

React--》React组件的三大核心属性

虽然能实现效果,但是未免有些过于繁琐,要知道我们在创建类的时候,如果不是通过new出来的实例传入的数据,我们完全可以把固定的数据写在构造器的外面,如下:

<script>
  class person {
    constructor(name,age){
      this.name = name
      this.age = age
    }
    // 类里面可以直接写赋值语句
    gender = '男'
  }
  const p1 = new person('张三',18)
  console.log(p1)
</script>

React--》React组件的三大核心属性

所以我们也可以将state状态写在构造器外面,构造器可以直接省略,通过箭头函数的this指向外层的this来达到修改state中this数据的目的:

<script type="text/babel">
  // 创建组件
  class Weather extends React.Component {
    // 初始化状态
    state = {isHot:true,wind:'微风'}
    render(){
      // 读取状态
      const {isHot,wind} = this.state
      return (
        <div>
          <h1>今天天气很{isHot ? '炎热' : '寒冷'},{wind}</h1>
          <button onClick={this.changeWeather}>点击切换天气</button>  
        </div>
      )
    }
    // 自定义方法---要用赋值语句的形式+箭头函数
    changeWeather = ()=> {
      const isHot = this.state.isHot
      this.setState({isHot:!isHot})
    }
  }
  // 渲染页面到组件
  ReactDOM.render(<Weather/>,document.getElementById('root'))
</script>

注意

1)组件中render方法中的this为组件实例对象。

2)组件自定义的方法中this为undefined,强制绑定this可以通过函数对象的bind()或箭头函数。

3)状态数据,不能直接修改或更新。

props

每个组件对象都会有 props 属性,组件标签的所有属性都保存在 props 中。其基本使用如下:

<script type="text/babel">
  // 创建组件
  class Person extends React.Component {
    render(){
      const {name,age,gender} = this.props
      return (
        <ul>
          <li>姓名: {name}</li>
          <li>年龄: {age}</li>
          <li>性别: {gender}</li>
        </ul>
      )
    }
  }
  // 渲染页面到组件
  ReactDOM.render(<Person name="张三" age="18" gender="男" />,document.getElementById('root'))
</script>

React--》React组件的三大核心属性

如果想批量传递props,可以通过以下方式:

React--》React组件的三大核心属性

构造器是否接受props,是否传递给super,取决于:是否希望在构造器中通过this访问props。

React--》React组件的三大核心属性

函数式组件使用props

<script type="text/babel">
  // 函数式组件使用props
  function Person(props){
    const {name,age,gender} = props
    return (
        <ul>
          <li>姓名: {name}</li>
          <li>年龄: {age}</li>
          <li>性别: {gender}</li>
        </ul>
    )
  }
  // 渲染页面到组件
  ReactDOM.render(<Person name="张三" age="18" gender="男"/>,document.getElementById('root'))
</script>

React--》React组件的三大核心属性

注意

1)通过标签属性从组件外向组件内传递变化的数据

2)props是只读的,组件内部不要修改props

refs

组件内的标签可以定义ref属性来标识自己

字符串形式的ref

<script type="text/babel">
  // 创建组件
  class Demo extends React.Component {
    // 展示输入框左侧的数据
    showData = ()=>{
      const {input1} = this.refs
      alert(input1.value)
    }
    // 展示输入框右侧的数据
    showData2 = ()=>{
      const {input2} = this.refs
      alert(input2.value)
    }
    render(){
      return (
        <div>
          <input ref="input1" type="text" placeholder="点击按钮显示数据" />&nbsp;  
          <button onClick={this.showData}>点我显示数据</button>&nbsp;
          <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
        </div>
      )
    }
  }
  // 渲染组件
  ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>

React--》React组件的三大核心属性

虽然这种方式很简单,但是存在一定的效率问题,官方文档明确说明不建议去使用它:

React--》React组件的三大核心属性

回调形式的ref

拿到当前ref所在的节点,react帮助我们调用函数然后传进来,之后挂载到实例自身上。

<script type="text/babel">
  // 创建组件
  class Demo extends React.Component {
    // 展示输入框左侧的数据
    showData = ()=>{
      const {input1} = this
      alert(input1.value)
    }
    // 展示输入框右侧的数据
    showData2 = ()=>{
      const {input2} = this
      alert(input2.value)
    }
    render(){
      return (
        <div>
          <input ref={c => this.input1 = c} type="text" placeholder="点击按钮显示数据" />&nbsp;  
          <button onClick={this.showData}>点我显示数据</button>&nbsp;
          <input ref={c => this.input2 = c} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
        </div>
      )
    }
  }
  // 渲染组件
  ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>

使用回调形式的ref会出现以下问题,如果想解决这个问题,可以用以下方式:

React--》React组件的三大核心属性

<script type="text/babel">
  // 创建组件
  class Demo extends React.Component {
    // 展示输入框的数据
    showData = ()=>{
      const {input1} = this
      alert(input1.value)
    }
    saveInput = (c)=>{
      this.input1 = c
      console.log('@');
    }
    render(){
      return (
        <div>
          {/*在JSX语法中,注释的书写方式是外层包裹大括号,表明里面是JS语法,写上注释即可表明当前为注释*/}
          <input ref={this.saveInput} type="text" placeholder="点击按钮显示数据" />&nbsp; 
          <button onClick={this.showData}>点我显示数据</button>&nbsp;
        </div>
      )
    }
  }
  // 渲染组件
  ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>

createRef的使用

React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点。但这种形式有一种缺点就是只能容纳一个元素进行使用,如果想出里多个元素需创建多个createRef容器。

<script type="text/babel">
  // 创建组件
  class Demo extends React.Component {
    // 创建容器
    myRef = React.createRef()
    myRef1 = React.createRef()
    // 展示输入框的数据
    showData = ()=>{
      console.log(this.myRef.current);
      alert(this.myRef.current.value)
    }
    showData1 = ()=>{
      console.log(this.myRef1.current);
    }
    render(){
      return (
        <div>
          {/*在JSX语法中,注释的书写方式是外层包裹大括号,表明里面是JS语法,写上注释即可表明当前为注释*/}
          <input ref={this.myRef} type="text" placeholder="点击按钮显示数据" />&nbsp; 
          <button onClick={this.showData}>点我显示数据</button>&nbsp;
          <input type="text" onBlur={this.showData1} ref={this.myRef1} placeholder="另一个input" />
        </div>
      )
    }
  }
  // 渲染组件
  ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>

React--》React组件的三大核心属性