翻译|Thinking Statefully

‌原文:Thinking Statefullyjavascript

熟练掌握React的过程包含了如何解决特定问题的方法转变.这提醒我,这个学习过程有点像在路上不一样的方向开车. 第一次感觉这一点是,我真正访问土耳其和卡斯柯岛,他们的车都靠左行驶.在美国咱们是靠右行驶,因此要花很大的力气重编程. 一出机场就差点完蛋了.java

有意思的是,即便我已经能够在正常的直道上行驶,可是在不一样状况发生时,大脑仍然把他转换成了旧的习惯.react

转进停车场?习惯接管了,我开进了错误的车道.在停车标志车左转?仍是一样的问题.向右转?你认为我已经了解了一切,可是对于个人大脑,彻底没这回事.git

我讲这个故事是由于在学习React的时候,个人经历是相似的.我想其余人也有这样的经历.github

传递props到组件(最好把组件当作是函数),大脑也已习惯了. 看起来和HTML的工做差很少.编程

在简单实例中,往下传递数据,向上传递事件也很好理解.这就是回掉模式,在其余的地方也很常见.向按钮组件传递一个onClick handler是至关普通.redux

可是若是须要Modal对话框.或者是提示Badge,要怎么操做?亦或者根据事件响应来对一个Icon进行动画操做?能够看到,这些都是命令式的,"事件驱动"的内容在声明式和状态时的React世界显得很不天然.数组

怎么开发"状态式"或者是"声明式"的思考

若是你有jQuery,Angular的经验或者其余框架的以经验,须要调用函数执行任务("过程式编程"),在React的领域里为了更为有效的工做就须要调整思惟模型.从实践中能够很快的完成这个转变-只须要给大脑一些新的实例或者"模式".框架

这里是一些实例函数

打开/关闭一个Accordion组件(手风琴组件)

旧有办法: 点击toggle按钮调用toggle函数,从而打开或者关闭accordion.Accordion组件知道该怎么关闭或打开. state方法: Accordion要么是"open"状态,要么是"close"状态. 这个信息咱们做为一个标记(flag)存储在Accordion组件的父组件state上(不在Accordion上存储).以名为isOpen的prop形式传递state信息,Accordion依据prop来进行渲染. 当isOpentrue时,渲染为打开,反之就关闭.

<Accordion isOpen={true}/>
// or
<Accordion isOpen={false}/>
复制代码

这个实例相对简单.但愿不要有什么认知负担. 最大的挑战是以声明式的React方法处理,打开/关闭的state是存储在Accordion组件以外,并以prop的形式传递的.

打开,关闭一个Dialog

‌旧有办法: 点击按钮打开modal,点击按钮关闭. state方法: Modal是开仍是闭是一个状态,"open","state"二者居其一.因此state是"open",咱们就渲染组件.若是是"close",就不作渲染.此外,能够给Modal传递onClose回调函数-经过这种方法,Modal组件的父组件决定了用户点击按钮时应该干什么

{this.state.isModalOpen && <Modal onClose={this.handleClose}/>} 复制代码

详细内容请看Modal Dialogs in React

提醒组件

‌旧有办法: 当一个事件发生时(例如一个错误),调用提示库的组件来显示popup,例如toast.error("Oh,no!")

state方法: 把提示做为一个state.有0个或者1个,或多个提示,保存在消息数组中. 在根组件处安置提醒组件. 传递state用于显示.你能够用不一样的方式来管理消息数组:

  • 若是使用Redux,保存在store中,Dispatch actions来添加消息
  • 若是不使用Redux,能够保存在根组件的state中,或者是一个单例对象(整个应用中只实例化一次的对象)中.而后就能够传递向组件传递addNotificationprop,或者导入能够添加到全局单例对象的函数.

在应用中,你可使用软件包来完成任务,例如react-redux-toastr.可是概念很简单,因此能够根据你的需求本身编写.

用动画显示改变

假设你有一个有数字的badge用于显示登陆的用户,组件从prop获取这个数字.可是若是你想在组件数字变化时有点动效,怎么处理?

‌老办法: 可使用jQuery来toggle(切换)一个执行动画的类([^译注:CSS的类]),或者直接用jQuery操控要执行动画的元素. state方法: 你能够在props改变时经过componentWillReceiveProps声明周期函数比较新旧值来响应变化.若是改变了,能够把"animating" state设置为true.接着执行render,当"animating"为trur时,添加一个执行动画的CSS类.为false时,不添加类.这里是代码:

componentWillReceiveProps(nextProps) {
if(this.props.counter !== nextProps.counter) {
  // Set animating to true right now. When that state change finishes,
  // set a timer to set animating false 200ms later.
  this.setState({ animating: true }, () => {
    setTimeout(() => {
      this.setState({ animating: false });
    }, 200);
  });
}
}

render() {
const animatingClass = this.state.animating ? 'animating' : '';
return (
  <div className={`badge ${animatingClass}`}> {this.props.counter} </div>
);
}
复制代码

完成

相关文章
相关标签/搜索