用React的属性和状态操作数据

简介: 管理数据对任何应用来说都非常重要。在UI中切换数据流是很有挑战性的。现在的web应用一般都具备复杂的UI结构。一个地方的数据变动都会直接或间接的影响到其他地方。对于这种问题,由Knockout.js和Angular.js实现的数据双向绑定是非常流行的解决方法。
管理数据对任何应用来说都非常重要。在UI中切换数据流是很有挑战性的。现在的web应用一般都具备复杂的UI结构。一个地方的数据变动都会直接或间接的影响到其他地方。对于这种问题,由Knockout.js和Angular.js实现的数据双向绑定是非常流行的解决方法。


对于一些应用(尤其是具有简单的数据流),双向绑定是非常高校的。而对于更加复杂的应用,数据双向绑定已被证明是非常低效的。对于实际的UI设计来说,俨然成为一种障碍。React不能解决应用数据流的大量问题(虽然Flux可以),但是基于它的一个组件可以。

有了这个组件,React可以处理数据流问题以及显示UI更新的结果。UI更新方面的问题是通过一种名为Reconciliation的模块解决的。这个模块涉及到一种虚拟DOM的新思路。在下篇文章中,我们会详细讲解Reconciliation。这篇文章我们主要关注数据流问题和React组件间使用的各种数据问题。

各种组件数据

React组件中数据是以属性或者状态的形式存储的。

属性相当于组件的输入值。他们通常用在组件的渲染和状态初始化的过程中。当组件实例化后,属性就应该确认不变了。属性值只有在实例化组件时才能被设置。这时,当组件再次在DOM中渲染时,React将会对新旧属性值做比较,以此来确定哪些DOM需要更新。

现在看一个设置属性值引起DOM更新的例子。

https://codepen.io/SitePoint/pen/XKqQqN

状态数据的变化一般是通过绑定组件的事件方法实现的。通常,更新状态会引起React组件的重新渲染。一个组件初始化之前,它的状态必须首先初始化。已经初始化的值包含常量值和属性值(上文提过的)。

对于像Angular.js之类的框架来说,属性是单向绑定的数据,状态是双向绑定的数据。这不是一个完美的比喻方式。Angular.js 使用一种具备两种使用方式的数据对象而React使用两种类型的数据对象,彼此都有特定的使用方式。

属性

我的以前React的文章(https://www.sitepoint.com/getting-started-react/)讲过指定和获取属性的语法。这篇文章通过多种代码范例讲解了Javascript和JSX中的静态属性和动态属性的使用方法。以这篇文章为基础,让我们看一些有趣的与属性操作相关的细节。

当需要给组件添加一个CSS的class属性时,我们必须用className代替class。React要求这个是因为ES2015将class作为定义对象的关键词。为了避免冲突,React将className作为替代品。如果使用了class作为属性名,React将会给出相关提示以此提醒开发者用className代替class。

注意观察下方不正确的class属性名,微软Edge浏览器会给出有用的警告信息。


当把class改为classname,警告信息随之消失。

当把class改为className,警告信息随之消失。查看下面来自CodeOpen的完整范例。

https://codepen.io/SitePoint/pen/akGxGW

除了像className这样的属性名称,React属性还有其他有趣的地方。比如,动态组件属性就是一个反模式。动态属性能够在组建实例化过程中被设置,但是组件实例化后动态属性就不能变化了。这个过程包括组件的实例化和渲染。一个组件的动态值可以被称为状态,它是通过state属性控制的而不是props属性。

在下面的实例代码中,通过createElement实例化一个名字为SomeComponent的组件,并给它添加了两个属性。

JavaScript:


var someComponent = React.createElement(SomeComponent);                                 
someComponent.props.prop1 = "some value";   
someComponent.props.prop2 = "some value";


JSX:


var someComponent = <SomeComponent />;
someComponent.props.prop1 = "some value";
someComponent.props.prop2 = "some value";


操作已经实例化的组件的props能够产生很难追踪的错误。当然,改变属性也不能引起组件的更新,因为属性已经与其组件不同步了。

因此,我们应该在组件的实例化过程中设置属性。代码如下:


JavaScript:


var someComponent = React.createElement(SomeComponent, {
  prop1: "some value",
  prop2: "some value"
});

JSX:


var someComponent = <SomeComponent prop1="some value" prop2="some value" />

然后,组件可以重新渲染,在这点上,React将执行核对过程,以确定新的属性值如何影响DOM。然后,DOM随着更改而更新。

有关DOM更新的例子,可以查看文章顶部第一个CodePen的例子。

状态

状态表示由组件更改的数据,通常通过与用户的交互来实现。为了方便这种更改,事件处理程序被注册为适当的DOM元素。当事件发生时,更新的值将从DOM检索,并通知新状态的组件。在组件可以利用状态之前,状态必须通过函数getinitialstate初始化。通常情况下,函数getinitialstate使用属性或者其他方式传过来的静态值初始化状态。


var Message = React.createClass({

  getInitialState: function() {
    return { message: this.props.message };
  },

初始化状态后,状态值可以像渲染组件时的属性值一样使用。为了捕获更新状态的用户交互,事件处理程序已经注册。为了保持React组件的独立性,事件处理函数对象可以作为属性传递,或者直接在组件对象本身上定义。

https://codepen.io/SitePoint/pen/JKvVvy

React的好处之一是使用标准的HTML事件。标准的HTML事件包含的是标准的HTML事件对象。不需要学习特殊事件库、事件处理程序或自定义事件对象。由于现代浏览器基本上兼容,所以不需要中间的跨浏览器库,如jQuery。

为了处理状态的变化,需要使用setstate函数在适当的状态属性下设置新值。调用此函数将使组件重新渲染。

如下图所示在Visual Studio代码编辑器,使用setstate函数是从_messagechange事件处理程序中调用。

总结

React组件提供了两种处理数据的机制:属性和状态。在不可变属性和可变状态之间划分数据更清楚地标识每种数据的作用,以及组件与它的关系。一般来说,属性是首选的,因为它们简化了数据流。状态对于捕获用户交互和其他UI事件产生的数据更新非常有用。

属性和状态之间的关系促进了数据通过组件的流动。当实例化和渲染组件时,属性可以用来初始化状态,状态值可以用来设置属性。来自用户交互的新值通过状态捕获,然后用于更新属性。

应用程序中较大的数据流通过一个称为Flux的模式完成。


本文为翻译作品,原文来自sitepoint,作者Eric Greene。原文地址:https://www.sitepoint.com/working-with-data-in-react-properties-state/



相关文章
|
24天前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
125 2
|
2月前
|
前端开发 JavaScript UED
react或者vue更改用户所属组,将页面所有数据进行替换(解决问题思路)____一个按钮使得页面所有接口重新请求
在React或Vue中,若需在更改用户所属组后更新页面所有数据但不刷新整个页面,可以通过改变路由出口的key值来实现。在用户切换组成功后,更新key值,这会触发React或Vue重新渲染路由出口下的所有组件,从而请求新的数据。这种方法避免了使用`window.location.reload()`导致的页面闪烁,提供了更流畅的用户体验。
52 1
react或者vue更改用户所属组,将页面所有数据进行替换(解决问题思路)____一个按钮使得页面所有接口重新请求
|
2月前
|
前端开发
React属性之context属性
React中的Context属性用于跨组件传递数据,通过Provider和Consumer组件实现数据的提供和消费。
34 3
|
23天前
|
前端开发 JavaScript API
React将组件作为属性传递的最佳实践
本文探讨了在React中将组件作为属性传递的三种常见方式:作为元素传递、作为组件传递、作为函数传递。通过构建带图标的按钮组件,对比分析了每种方式的优缺点,最终推荐将组件作为函数传递,因为它提供了更好的可控性、灵活性和可扩展性。
30 0
|
2月前
|
前端开发
react中使用Modal.confirm数据不更新的问题解决
文章讨论了在React中使用Ant Design的`Modal.confirm`时更新数据不生效的问题,并提供了解决方案。原因是React状态更新可能是异步的,导致Modal的内容更新后不会立即反映在UI上。解决办法是在状态更新后使用`useEffect`钩子来调用Modal实例的`update`方法,从而更新Modal的内容。
60 0
react中使用Modal.confirm数据不更新的问题解决
|
2月前
|
前端开发 JavaScript
React 中的 props 属性传递技巧
【9月更文挑战第6天】本文详细介绍了React中`props`的基本用法,包括传递基本数据类型、对象和数组。文章通过多个代码示例展示了如何正确使用`props`,并探讨了常见的问题及解决方法,如`props`不可变性、默认值设置及类型检查等。正确掌握这些技巧有助于提升编程效率,编写出更健壮的代码。
54 13
|
2月前
|
前端开发
React使用hooks遇到的坑_state中的某几个属性数据变成了空字符
本文讨论了在React使用hooks时遇到的一个问题:state中的某些属性数据变成了空字符。作者通过在修改函数中重新解构赋值来获取最新的state值,解决了因数据更新不及时导致的问题。
54 0
|
3月前
|
存储 前端开发 JavaScript
|
3月前
|
开发者 Java
JSF EL 表达式:乘技术潮流之风,筑简洁开发之梦,触动开发者心弦的强大语言
【8月更文挑战第31天】JavaServer Faces (JSF) 的表达式语言 (EL) 是一种强大的工具,允许开发者在 JSF 页面和后台 bean 间进行简洁高效的数据绑定。本文介绍了 JSF EL 的基本概念及使用技巧,包括访问 bean 属性和方法、数据绑定、内置对象使用、条件判断和循环等,并分享了最佳实践建议,帮助提升开发效率和代码质量。
40 0
|
3月前
|
前端开发 API 开发者
【前端数据革命】React与GraphQL协同工作:从理论到实践全面解析现代前端数据获取的新范式,开启高效开发之旅!
【8月更文挑战第31天】本文通过具体代码示例,介绍了如何利用 GraphQL 和 React 搭建高效的前端数据获取系统。GraphQL 作为一种新型数据查询语言,能精准获取所需数据、提供强大的类型系统、统一的 API 入口及实时数据订阅功能,有效解决了 RESTful API 在复杂前端应用中遇到的问题。通过集成 Apollo Client,React 应用能轻松实现数据查询与实时更新,大幅提升性能与用户体验。文章详细讲解了从安装配置到查询订阅的全过程,并分享了实践心得,适合各层次前端开发者学习参考。
37 0