React知识点回忆(二)

一、组件 & Props

1、在函数组件中使用 props

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- 定义字符编码 -->
  <meta charset="UTF-8">
  <!-- 引入react核心库 -->
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <!-- 引入react-dome 支持react操作dom -->
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <!-- 引入babel 将jsx转换为js -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  <!-- 定义网页标题 -->
  <title>React</title>
</head>
<body>
  <div id="box"></div>
  <script type="text/babel">

  function Cpn(props) {
    return (
      <div>
        <span>name:{props.name}</span>
      </div>
    )
  }

  ReactDOM.render(<Cpn name="Ralph" />, document.getElementById('box'))
  </script>
</body>
</html>

props属性是默认传递的,默认值是一个空对象,它会自动收集定义在组件上的属性,并绑定到props对象上。

  • 当属性过多时,我们可以使用对象的方式传递 attr

    <script type="text/babel">
    
    function Cpn(props) {
      return (
        <div>
          <p>name:{props.name}</p>
          <p>age:{props.age}</p>
          <p>gender:{props.gender}</p>
        </div>
      )
    }
    
    // 定义需要传递的属性
    const attr = {
      name: 'Ralph',
      age: 20,
      gender: 'man'
    }
    
    ReactDOM.render(<Cpn {...attr} />, document.getElementById('box'))
    </script>
    

    注意:扩展运算符是不能直接去扩展一个对象的,因为对象不存在 iterator接口的,所以我们需要通过 {...obj} 的形式扩展一个对象,在 React{} 并不是代表一个对象,而是说明在此处可以使用javascript表达式,React 会自动去识别当前的对象并将其扩展。

  • 通过 prop-types 依赖包对props属性的类型进行检查

    1、引入 prop-type 依赖包

    <script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>
    

    2、设置实例静态属性 propTypes 定义属性的接收类型

    Cpn.propTypes = {
      name: PropTypes.string.isRequired,
      age: PropTypes.number.isRequired,
      gender: PropTypes.string
    }
    

    上述代码中,PropTypes 是由 prop-types 依赖包所提供的关键字,它对外提供了一系列 验证器 ,可用于确保组件接收到的数据类型是有效的。string 代表定义的属性必须为字符串类型,isRequired 代表定义的属性是必传的。

    3、对props中的属性定义初始值(默认值)

    Cpn.defaultProps = {
      gender: 'man'
    }
    

2、在类组件中使用 props

<script type="text/babel">

  class Cpn extends React.Component {
    render (){
      return (
        <div>
          <p>name:{this.props.name}</p>
          <p>age:{this.props.age}</p>
          <p>gender:{this.props.gender}</p>
        </div>
      )
    }
  }

    // 定义属性的类型
  Cpn.propTypes = {
    name: PropTypes.string.isRequired,
    age: PropTypes.number.isRequired,
    gender: PropTypes.string
  }

  Cpn.defaultProps = {
    gender: 'man'
  }

  // 定义需要传递的属性
  const attr = {
    name: 'Ralph',
    age: 20
  }

  ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
</script>

细心观察,可以发现类组件中的render函数中,我们可以使用 this.props 拿到父组件传递过来的 props,我们不妨可以大胆猜测,当我们自定义一个函数时,是否同样也能通过 this.props 拿到我们想要的结果。

  <script type="text/babel">

    class Cpn extends React.Component {
      constructor() {
        this.getProps()
      }

      render (){
        return (
          <div>
            <p>name:{this.props.name}</p>
            <p>age:{this.props.age}</p>
            <p>gender:{this.props.gender}</p>
          </div>
        )
      }

      // 自定义方法
      getProps (){
        console.log(this.props)
      }
    }

    // 定义属性的类型
    Cpn.propTypes = {
      name: PropTypes.string.isRequired,
      age: PropTypes.number.isRequired,
      gender: PropTypes.string
    }

    Cpn.defaultProps = {
      gender: 'man'
    }

    // 定义需要传递的属性
    const attr = {
      name: 'Ralph',
      age: 20
    }

    ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
  </script>

运行效果如下:
在这里插入图片描述
我们仔细观察报错信息,不难发现,它是想提示我们要在this之前去调用一次 super,好的,我们按照提示加上这个关键字

  <script type="text/babel">

    class Cpn extends React.Component {
      constructor() {
        super()
        this.getProps()
      }

      render (){
        return (
          <div>
            <p>name:{this.props.name}</p>
            <p>age:{this.props.age}</p>
            <p>gender:{this.props.gender}</p>
          </div>
        )
      }

      // 自定义方法
      getProps (){
        console.log(this.props)
      }
    }

    // 定义属性的类型
    Cpn.propTypes = {
      name: PropTypes.string.isRequired,
      age: PropTypes.number.isRequired,
      gender: PropTypes.string
    }

    Cpn.defaultProps = {
      gender: 'man'
    }

    // 定义需要传递的属性
    const attr = {
      name: 'Ralph',
      age: 20
    }

    ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
  </script>

运行效果如下:
在这里插入图片描述
我们再去仔细阅读官网,官网上有这样一句话:Class 组件应该始终使用 props 参数来调用父类的构造函数。 好的,我改!!!

  <script type="text/babel">

    class Cpn extends React.Component {
      constructor(props) {
        super(props)
        this.getProps()
      }

      render (){
        return (
          <div>
            <p>name:{this.props.name}</p>
            <p>age:{this.props.age}</p>
            <p>gender:{this.props.gender}</p>
          </div>
        )
      }

      // 自定义方法
      getProps (){
        console.log(this.props)
      }
    }

    // 定义属性的类型
    Cpn.propTypes = {
      name: PropTypes.string.isRequired,
      age: PropTypes.number.isRequired,
      gender: PropTypes.string
    }

    Cpn.defaultProps = {
      gender: 'man'
    }

    // 定义需要传递的属性
    const attr = {
      name: 'Ralph',
      age: 20
    }

    ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
  </script>

效果如下:
在这里插入图片描述
此时,效果正是我们想要的效果,并得到一条结论:当我们重写构造函数时应该要通过 super 关键字调用父类构造函数,并传入props作为参数

接下来让我们利用 Es6 语法改善一下代码

  <script type="text/babel">

    class Cpn extends React.Component {

	  static defaultProps = {
         gender: 'man'
      }

	  static propTypes = {
        name: PropTypes.string.isRequired,
        age: PropTypes.number.isRequired,
        gender: PropTypes.string
      }

      render (){
        return (
           <div>
             <p>name:{this.props.name}</p>
             <p>age:{this.props.age}</p>
             <p>gender:{this.props.gender}</p>
           </div>
         )
       }
      
    }

    // 定义需要传递的属性
    const attr = {
      name: 'Ralph',
      age: 20
    }

    ReactDOM.render(<Cpn { ...attr } />, document.getElementById('box'))
  </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@Ralph

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值