摘要:那什么时候使用受控组件,什么时候使用非受控组件呢我们知道受控组件是比较符合我们传统组件开发的思路的。故最基本的组件编写套路就这些。
上一篇讲了 React 两种最常见的组件:受控组件和非受控组件。为了可用性,我们一般编写出来的组件希望支持这两种特性:可以通过组件自身的方法来改变组件的某(些)状态,也可以通过 props 的值的变化来改变组件自身的同一个(些)状态。
组件改变自己的状态只能通过改变 state 完成,而把 props 的变化反映到 state 却是可以通过生命周期函数来实现。首先还是拿上一篇中受控 alert 组件代码为例:
class Alert extends React.Component { constructor( props ) { super( props ) this.state = { content: "", show: false } this.show = ( content )=>{ this.setState( { content: content, show: true } ) } this.hide = ()=>{ this.setState( { show: false } ) } } render() { let style = { display: this.state.show ? "fixed" : "none" } return (); } }Alert{ this.state.content }
组件初始化的时候构造函数会接受传入的 props ,而当组件的容器改变传入组件的 props 的值时会触发组件的 componentWillReceiveProps 的方法,在这个方法中我们可以把变化后的 props(nextProps) 通过 setState 映射成 state 的变化。那么我们需要做的就是给受控组件增加初始化 props 处理和在 componentWillReceiveProps 内 props 的处理。
class Alert extends React.Component { constructor( props ) { super( props ) this.state = { content: this.props.content || "", show: this.props.show || false } this.show = ( content )=>{ this.setState( { content: content, show: true } ) } this.hide = ()=>{ this.setState( { show: false } ) } } componentWillReceiveProps( nextProps ) { this.setState( nextProps ); } render() { let style = { display: this.state.show ? "fixed" : "none" } return (); } }Alert{ this.state.content }
那么针对同一个 alert 组件的使用就变得多样化,可以根据自己项目的需求来变化。譬如:
import { Alert } from "Alert"; class App extends React.Component { constructor() { super(); this.state = { alertMsg: "", showAlert: false } this.saveHandler = ()=>{ // save ajax success this.refs.myAlert.show( "Save successfully" ); } this.removeHandler = ()=>{ // remove ajax success this.setState( { alertMsg: "Remove successfully", showAlert: true } ) } } render() {} }
为了让组件更健壮,我们对 state 和 props 的一些必须的初始化值(默认值)需要明确指定
class Alert extends React.Component { constructor( props ) { super( props ) let content = this.props.content; let show = this.props.show; /* props.xxx 的优先级比 props.defautXxx 高, 如果设置了props.xxx 则 props.defaultXxx 就不起作用 */ this.state = { content: content === undefined ? this.props.defaultContent : content show: show === undefined ? this.props.defaultShow : show } } } Alert.propTypes = { defaultShow: React.PropTypes.bool, defaultContent: React.PropTypes.string, show: React.PropTypes.bool, content: React.PropTypes.string } Alert.defaultProps = { defaultShow: false, defaultContent: "" }
如上代码如果对 props.xxx 和 props.defaultXxx 有迷惑的童鞋,其实有了 xxx 完全没有必要再有 defaultXxx,但是参考一些组件库的 api 设计,我理解为是为了保持受控组件 api 的统一性,如果把 alert 组件当成受控组件则初始化使用 defaultXxx,如果当成非受控组件就直接使用 xxx。
那什么时候使用受控组件,什么时候使用非受控组件呢?我们知道受控组件是比较符合我们传统 UI 组件开发的思路的。但是 React 在跨组件通讯方面很弱,如果不借助第三方库进行通讯,对于两个毫无关系的组件相互调用就需要传递层层的回调函数。我想没有人喜欢这种编程风格,所以把所有组件的状态抽象到一个地方进行集中管理变化,典型的数据流用 redux 就倾向于使用非受控组件了(这里不讨论flux思想的由来,不讨论redux好坏)。
故最基本的 React 组件编写套路就这些。但是这些还只是 api 应用层面的东西,比较难的是在编写组件时候对状态的抽象,使使用者使用的舒服自然。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/82956.html
摘要:受控组件例假设有一个方法非受控组件例接下来我们来看下如果编写这两种组件,打个比方我们要自定义一个组件。于是修改后的代码如下确定使用这个组件的代码以上就是两种组件的编写思路,你可以选择把你的组件编写成任意一种,那么使用者使用时也会有所不同。 新手写 React 组件往往无从入手,怎么写,什么时候用 props,什么时候用 state 摸不着头脑。其实是没有了解到 React 的一些思想。...
摘要:到此,就初步实现了一个组件是服务端渲染。服务端渲染完成页面结构,浏览器端渲染完成事件绑定。但是,在服务端渲染中却出现了问题。根据这个思路,服务端渲染中异步数据的获取功能就完成啦。 大家好,我是神三元,这一次,让我们来以React为例,把服务端渲染(Server Side Render,简称SSR)学个明明白白。 这里附上这个项目的github地址:https://github.com/...
摘要:简介来构建用户界面的库,不是框架关注于层虚拟单向数据流这些概念如何使用下载文件也可以使用,需要用到的模块介绍是编写组件的一种语法规范,可以看为是的扩展,它支持将和混写在一起,最后使用编译为常规的,方便浏览器解析编写第一个例子使用编写组件 react简介 来构建用户界面的库,不是框架 关注于view层 虚拟DOM 单向数据流 JSX这些概念 如何使用react 下载文件 rea...
摘要:其他的项目使用了拼装样式验证传入的属性是否是函数验证父组件传入的数据格式是否正确五参考文献谈谈的使用使用场景 仿 taro-ui 实现 modal 组件 小程序组件. 简介: 项目中使用到弹窗类的组件,重新制造了一个轮子. 源码地址: https://github.com/xiangxiong... 编写完modal组件总计花了28分钟. 效果图: showImg(htt...
摘要:其他的项目使用了拼装样式验证传入的属性是否是函数验证父组件传入的数据格式是否正确五参考文献谈谈的使用使用场景 仿 taro-ui 实现 modal 组件 小程序组件. 简介: 项目中使用到弹窗类的组件,重新制造了一个轮子. 源码地址: https://github.com/xiangxiong... 编写完modal组件总计花了28分钟. 效果图: showImg(htt...
阅读 2067·2021-11-24 09:39
阅读 773·2021-09-30 09:48
阅读 974·2021-09-22 15:29
阅读 2409·2019-08-30 14:17
阅读 1884·2019-08-30 13:50
阅读 1336·2019-08-30 13:47
阅读 977·2019-08-30 13:19
阅读 3416·2019-08-29 16:43