资讯专栏INFORMATION COLUMN

React.js 小书 Lesson11 - 配置组件的 props

xiangzhihong / 1386人阅读

摘要:默认配置上面的组件默认配置我们是通过操作符来实现。但这并不意味着由决定的显示形态不能被修改。组件可以在内部通过获取到配置参数,组件可以根据的不同来确定自己的显示形态,达到可配置的效果。下一节中我们将介绍小书。

React.js 小书 Lesson11 - 配置组件的 props

本文作者:胡子大哈
本文原文:http://huziketang.com/books/react/lesson11

转载请注明出处,保留原文链接以及作者信息

在线阅读:http://huziketang.com/books/react

组件是相互独立、可复用的单元,一个组件可能在不同地方被用到。但是在不同的场景下对这个组件的需求可能会根据情况有所不同,例如一个点赞按钮组件,在我这里需要它显示的文本是“点赞”和“取消”,当别的同事拿过去用的时候,却需要它显示“赞”和“已赞”。如何让组件能适应不同场景下的需求,我们就要让组件具有一定的“可配置”性。

React.js 的 props 就可以帮助我们达到这个效果。每个组件都可以接受一个 props 参数,它是一个对象,包含了所有你对这个组件的配置。就拿我们点赞按钮做例子:

下面的代码可以让它达到上述的可配置性:

class LikeButton extends Component {
  constructor () {
    super()
    this.state = { isLiked: false }
  }

  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
  }

  render () {
    const likedText = this.props.likedText || "取消"
    const unlikedText = this.props.unlikedText || "点赞"
    return (
      
    )
  }
}

render 函数可以看出来,组件内部是通过 this.props 的方式获取到组件的参数的,如果 this.props 里面有需要的属性我们就采用相应的属性,没有的话就用默认的属性。

那么怎么把 props 传进去呢?在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为 props 对象的键值

class Index extends Component {
  render () {
    return (
      
) } }

就像你在用普通的 HTML 标签的属性一样,可以把参数放在表示组件的标签上,组件内部就可以通过 this.props 来访问到这些配置参数了。

前面的章节我们说过,JSX 的表达式插入可以在标签属性上使用。所以其实可以把任何类型的数据作为组件的参数,包括字符串、数字、对象、数组、甚至是函数等等。例如现在我们把一个对象传给点赞组件作为参数:

class Index extends Component {
  render () {
    return (
      
) } }

现在我们把 likedTextunlikedText 这两个参数封装到一个叫 wordings 的对象参数内,然后传入点赞组件中。大家看到 {{likedText: "已赞", unlikedText: "赞"}} 这样的代码的时候,不要以为是什么新语法。之前讨论过,JSX 的 {} 内可以嵌入任何表达式,{{}} 就是在 {} 内部用对象字面量返回一个对象而已。

这时候,点赞按钮的内部就要用 this.props.wordings 来获取到到参数了:

class LikeButton extends Component {
  constructor () {
    super()
    this.state = { isLiked: false }
  }

  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
  }

  render () {
    const wordings = this.props.wordings || {
      likedText: "取消",
      unlikedText: "点赞"
    }
    return (
      
    )
  }
}

甚至可以往组件内部传入函数作为参数:

class Index extends Component {
  render () {
    return (
      
console.log("Click on like button!")}/>
) } }

这样可以通过 this.props.onClick 获取到这个传进去的函数,修改 LikeButton handleClickOnLikeButton 方法:

...
  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
    if (this.props.onClick) {
      this.props.onClick()
    }
  }
...

当每次点击按钮的时候,控制台会显示 Click on like button! 。但这个行为不是点赞组件自己实现的,而是我们传进去的。所以,一个组件的行为、显示形态都可以用 props 来控制,就可以达到很好的可配置性。

默认配置 defaultProps

上面的组件默认配置我们是通过 || 操作符来实现。这种需要默认配置的情况在 React.js 中非常常见,所以 React.js 也提供了一种方式 defaultProps,可以方便的做到默认配置。

class LikeButton extends Component {
  static defaultProps = {
    likedText: "取消",
    unlikedText: "点赞"
  }

  constructor () {
    super()
    this.state = { isLiked: false }
  }

  handleClickOnLikeButton () {
    this.setState({
      isLiked: !this.state.isLiked
    })
  }

  render () {
    return (
      
    )
  }
}

注意,我们给点赞组件加上了以下的代码:

  static defaultProps = {
    likedText: "取消",
    unlikedText: "点赞"
  }

defaultProps 作为点赞按钮组件的类属性,里面是对 props 中各个属性的默认配置。这样我们就不需要判断配置属性是否传进来了:如果没有传进来,会直接使用 defaultProps 中的默认属性。 所以可以看到,在 render 函数中,我们会直接使用 this.props 而不需要再做判断。

props 不可变

props 一旦传入进来就不能改变。修改上面的例子中的 handleClickOnLikeButton

...
  handleClickOnLikeButton () {
    this.props.likedText = "取消"
    this.setState({
      isLiked: !this.state.isLiked
    })
  }
...

我们尝试在用户点击按钮的时候改变 this.props.likedText ,然后你会看到控制台报错了:

你不能改变一个组件被渲染的时候传进来的 props。React.js 希望一个组件在输入确定的 props 的时候,能够输出确定的 UI 显示形态。如果 props 渲染过程中可以被修改,那么就会导致这个组件显示形态和行为变得不可预测,这样会可能会给组件使用者带来困惑。

但这并不意味着由 props 决定的显示形态不能被修改。组件的使用者可以主动地通过重新渲染的方式把新的 props 传入组件当中,这样这个组件中由 props 决定的显示形态也会得到相应的改变。

修改上面的例子的 Index 组件:

class Index extends Component {
  constructor () {
    super()
    this.state = {
      likedText: "已赞",
      unlikedText: "赞"
    }
  }

  handleClickOnChange () {
    this.setState({
      likedText: "取消",
      unlikedText: "点赞"
    })
  }

  render () {
    return (
      
) } }

在这里,我们把 Indexstate 中的 likedTextunlikedText 传给 LikeButtonIndex 还有另外一个按钮,点击这个按钮会通过 setState 修改 Indexstate 中的两个属性。

由于 setState 会导致 Index 重新渲染,所以 LikedButton 会接收到新的 props,并且重新渲染,于是它的显示形态也会得到更新。这就是通过重新渲染的方式来传入新的 props 从而达到修改 LikedButton 显示形态的效果。

总结

为了使得组件的可定制性更强,在使用组件的时候,可以在标签上加属性来传入配置参数。

组件可以在内部通过 this.props 获取到配置参数,组件可以根据 props 的不同来确定自己的显示形态,达到可配置的效果。

可以通过给组件添加类属性 defaultProps 来配置默认参数。

props 一旦传入,你就不可以在组件内部对它进行修改。但是你可以通过父组件主动重新渲染的方式来传入新的 props,从而达到更新的效果。

下一节中我们将介绍《React.js 小书 Lesson12 - state vs props》。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89663.html

相关文章

  • 写一本关于 React.js 小书

    摘要:因为工作中一直在使用,也一直以来想总结一下自己关于的一些知识经验。于是把一些想法慢慢整理书写下来,做成一本开源免费专业简单的入门级别的小书,提供给社区。本书的后续可能会做成视频版本,敬请期待。本作品采用署名禁止演绎国际许可协议进行许可 React.js 小书 本文作者:胡子大哈本文原文:React.js 小书 转载请注明出处,保留原文链接以及作者信息 在线阅读:http://huzi...

    Scorpion 评论0 收藏0
  • React.js 小书 Lesson12 - state vs props

    摘要:的主要作用是用于组件保存控制修改自己的可变状态。它们都可以决定组件的行为和显示形态。但是它们的职责其实非常明晰分明是让组件控制自己的状态,是让外部对组件自己进行配置。下一节中我们将介绍小书渲染列表数据。 React.js 小书 Lesson12 - state vs props 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/lesso...

    call_me_R 评论0 收藏0
  • React.js 小书 Lesson10 - 组件 state 和 setState

    摘要:传入一个对象的时候,这个对象表示该组件的新状态。下一节中我们将介绍小书配置组件的。 React.js 小书 Lesson10 - 组件的 state 和 setState 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/lesson10 转载请注明出处,保留原文链接以及作者信息 在线阅读:http://huziketang.com/bo...

    tyheist 评论0 收藏0
  • React.js 小书 Lesson4 - 前端组件化(三):抽象出公共组件

    摘要:最后抽离出来了一个类,可以帮助我们更好的做组件化。一个组件有自己的显示形态上面的结构和内容行为,组件的显示形态和行为可以由数据状态和配置参数共同决定。接下来我们开始正式进入主题,开始正式介绍。下一节链接直达小书基本环境安装 React.js 小书 Lesson4 - 前端组件化(三):抽象出公共组件类 本文作者:胡子大哈本文原文:http://huziketang.com/books...

    jsbintask 评论0 收藏0
  • React.js 小书 Lesson22 - props.children 和容器类组件

    摘要:由于会把插入表达式里面数组中的一个个罗列下来显示。这样通过这个布局组件,就可以在各个地方高度复用我们的布局。嵌套的结构在组件内部都可以通过获取到,这种组件编写方式在编写容器类型的组件当中非常有用。下一节中我们将介绍小书和属性。 React.js 小书 Lesson22 - props.children 和容器类组件 本文作者:胡子大哈本文原文:http://huziketang.co...

    番茄西红柿 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<