這篇文章要跟大家分享的內容是關於Pastate.js 響應式react 框架之表單渲染與操作 ,有著一定的參考價值,有需要的朋友可以參考一下
這是Pastate.js響應式react state 管理框架系列教學的第四章,歡迎關注,並持續更新。 Pastate.js Github
這一章,讓我們來看看如何在 pastate 裡渲染和操作表單元素。
使用原生表單元素
我們在 BasicInfoView
元件的兩個按鈕下方新增一個輸入方塊用於輸入姓名,並新增一個勾選方塊用於選擇性別,更改如下:
class BasicInfoView extends PureComponent { render() { ... return ( <p style={{ padding: 10, margin: 10 }}> ... <p> <button onClick={this.decreaseAge}> decrease age </button> <button onClick={this.increaseAge}> increase age </button> </p> <p> name: <input type="text" value={state.name} onChange={this.handleNameChange}/> <br /> Is boy: <input type="checkbox" checked={state.isBoy == true} onChange={this.handleIsBoyChange}/> </p> </p> ) } }
上面新增兩個了input 標籤,第一個input 使用name 資料, 第二個input 使用isBoy 資料。同時我們也先指定兩個 input 的 onChange 處理函數。
注意:如前面章節所提及,對於 imState 布林值,請記得使用明確布林值方式:checked={state.isBoy == true}
。
接下來看看如何實作兩個 onChange 處理函數:
class BasicInfoView extends PureComponent { ... handleNameChange(e){ state.basicInfo.name = e.target.value store.sync() // 编辑中的输入框,需手动同步store } handleIsBoyChange(e){ state.basicInfo.isBoy = e.target.checked } ... }
非常熟悉且簡單!你只要把更新的值賦給目標state節點。我們會發現多了一個 store.sync()
,這個函數就是讓 pastate 立刻執行資料同步更新。由於許多輸入法會在輸入過程中會把帶下劃線的「拼音字母」 輸入到input 中,如下:
編輯中的輸入框 時,需要簡單地使用 store.sync() 執行同步更新,讓「拼音” 連續。如果不是對
編輯中的輸入框 進行修改或不需要支援輸入法輸入(如密碼等),則無需使用 store.sync() 。
class BasicInfoView extends PureComponent { ... // 把输入值都转化为大写 handleNameChange_uppercase(e){ state.basicInfo.name = e.target.value.toUpperCase() store.sync() } // 控制文本长度在10个字符以内 handleNameChange_limitedLength(e){ if(e.target.value.length > 10) return; state.basicInfo.name = e.target.value store.sync() } ... }使用pastate 雙向綁定輸入元件使用過vue.js 或angular.js 的人都體驗過自動雙向資料綁定(two-ways data binding) 的便捷性,但由於react state 渲染的單向資料流原則,在react 中沒有預設提供這個功能。而 pastate 的 imState 具有保存節點資訊的特殊性,能夠輕鬆實現自動雙向資料綁定功能! pastate 為你提供了四個已實現雙向資料綁定的高階表單元件(Higher Order Component, 通常簡稱HOC) ,這些元件都是基於PureComponent 實現的,具有良好的渲染性能,你可以盡情享用他們!這四個表單元件如下:
Input
: 文字方塊
- ##Checkbox
: 複選框
- RadioGroup
: 單選框選項組
- Select
: 下拉選擇框
Input 文字方塊
Input 元件可以用來顯示單行輸入框和多行輸入框,只需要傳入要綁定的值,當你透過介面當更改輸入框的值時,Input 元件會自動為你更新所綁定的state :
import { ..., Input } from 'pastate' ... render(){ let state = this.props.state return( ... <Input value={state.text1} /> {/** 单行输入框,内部使用 <input type="text" /> 实现 */} <Input value={state.text2} type="textarea" /> {/** 多行输入框,内部使用 <textarea /> 实现 */} ... ) } ...
Input 元件的屬性及其說明如下:
屬性| 值| 說明
# value | string | number , 必填 | 绑定的值,需要使用 this.props.state 中的节点 , 即 imState
type | "text" | "textarea" | "password" | "number" | 输入框类型,默认为 "text"
beforeChange | (newValue: string | number, oldValue: string | number) => string | number | 在绑定值更新前会被调用,可用于实现自定义字符串更新逻辑, 如控制大小写或限制字符串长度等;返回值为最终要更新的值
afterChange | (newValue: string | number) => void | 在绑定值更新后会被调用
disabled | boolean | 指定输入框是否处于禁止状态,默认为 false
className | string | 传递给输入框的 class 名 ( 用于指定 css 样式等 )
id | string | 传递给输入框的 id 名 ( 用于指定 css 样式等 )
useComposedValue | boolean | [ 实验特性 ] 指定是否在输入法完成拼音过程时才更新 state 的模式,开启后,在输入拼音的过程中绑定的值不会更新,默认为 falseInput 组件实现了自动绑定数据双向绑定功能,如果你需要自定义字符串更新逻辑,或者在字符值更新后做一些操作,可以通过指定可选的 beforeChange 函数和 afterChange 函数来实现。
... handleTextBeforeChange(newValue, oldValue) { // 把输入的字符转化为大写 return newValue.toUpperCase() } render(){ let state = this.props.state return( ... <Input value={state.text1} beforeChange={this.handleTextBeforeChange} /> ... ) } ...
Input 组件的属性 useComposedValue 开启后,可以实现在输入法输入拼音的过程中绑定的值不会更新的功能,等拼音输入完成后 state 值才更新,减少拼音输入过程中不必要的 state 更新和视图渲染动作:
useComposedValue 属性目前为实验特性,如果发现在某个浏览器或某种输入法中有问题,欢迎提交 issue 。
Checkbox 复选框
每个 Checkbox 是一个勾选框组件,只需传递要绑定的布尔值 state 节点,即可完成绑定:
import { ..., Checkbox } from 'pastate' ... render(){ let state = this.props.state return( ... I am a boy: <Checkbox value={state.isBoy} /> ... ) } ...
Checkbox 组件的属性及其说明如下:
属性 | 值 | 说明
value | boolean,必填 | 绑定的数据值,可直接传入 this.props.state 中的节点值,无需做
state.xxx == true
转化。
afterChange | (newValue: boolean) => void | 在绑定值更新后会被调用
disabled | boolean | 指定禁止点击状态,默认为 false
className | string | 传递 class 名 ( 用于指定 css 样式等 )
id | string | 传递 id 名 ( 用于指定 css 样式等 )RadioGroup 单选框选项组
RadioGroup 是一个单选框选项组,只要传入选项数组 options 常数和要绑定的选项值 value, 即可完成绑定:
import { ..., RadioGroup } from 'pastate' const goodNames = ['Peter', 'Tom', 'Allen'] ... render(){ let state = this.props.state return( ... Choose a name: <RadioGroup options={goodNames} value={state.name}/> ... ) } ...
RadioGroup 组件的属性及其说明如下:
属性 | 值 | 说明
options | Array
| Array, 必填 | 选项数据数组
value | string | number | boolean,必填 | 绑定的选中值
disabled | boolean | 指定禁止选择状态,默认为 false
vertical | boolean | 指定选项为垂直排列状态,默认为 false
afterChange | (newValue: string | number | boolean) => void | 在绑定值更新后会被调用
id | string | 传递给选项组根元素的 id
className | string | 传递给选项组根元素的 className
radioClassName | string | 传递给圆形按钮的 className
tagClassName | string | 传递给选项标签的 className
disabledTagClassName | string | 传递给禁用状态的选项标签的附加的 classNameoptions 属性接受两种格式的选项数据格式:
// 简单格式: Array<string> const nameOptions = ['Peter', 'Tom', 'Allen'] // 完备格式: Array<{value: string, tag: string, disabled?: boolean}> const nameOptionsChinese = [{ value: 'Peter', // 数据值 tag: '彼得', // 选项标签值 disabled: true // 可选地指定某个选项为不可选 },{ value: 'Tom', tag: '汤姆' },{ value: 'Allen', tag: '艾伦' }]
RadioGroup
是基于 PureComponent 实现的,对于 options 属性的值,建议定义一个 文件级 的选项数组常量, 这样可以提高渲染效率。如果把 options 值定义在 render 函数里或写成直接赋值的匿名对象(<radiogroup options='{["a",' ...></radiogroup>
), 在每次父组件渲染时,无论绑定的 value 数据有没有更新,RadioGroup 获取到的 options 属性的引用值都不一样,会使 RadioGroup 进行多余的渲染动作。 当你使用其他基于 PureComponent 实现的组件时,在向其传递数组 / 对象类型的常量的时候也可以做这样的性能优化。Select 下拉选择框
Select 是一个选择框组件,使用方法与 RadioGroup 类似,只要传入选项数组和要绑定的选择值即可完成绑定:
import { ..., Select } from 'pastate' const nameOptionsChinese = [{ value: 'DEFAULT', tag: '请选择', disabled: true },{ value: 'Peter', tag: '彼得' }, { value: 'Tom', tag: '汤姆' }, { value: 'Allen', tag: '艾伦' }] ... render(){ let state = this.props.state return( ... Choose a name: <Select options={nameOptionsChinese} value={state.name}/> ... ) } ...
Seclect 组件的属性及其说明如下:
属性 | 值 | 说明
options | Array
| Array, 必填 | 选项数据数组
value | string | number | boolean,必填 | 绑定的选中值
disabled | boolean | 指定禁止点击状态,默认为 false
afterChange | (newValue: string | number | boolean) => void | 在绑定值更新后会被调用
id | string | 传递的 id
className | string | 传递的 className如有需要显示没有选择的状态,可以多设置一个选项元素,通过元素的 tag 设置其提示文本, 并把元素的 disabled 设为 true 即可,没选中时的 value 值自行定义,不可为 null 或 undefined:
const nameOptionsChinese = [{ value: 'DEFAULT', tag: '请选择', disabled: true }, ... ]
Seclect 组件目前仅支持最常用的单选功能,以后将支持多选功能。
pastate 表单组件的类型定义
Pastate 的高阶组件均是使用 Typescript 进行开发 , 提供完整的类型定义文件,当你在 javascript 项目使用它们时,也可以得到良好的组件属性 intelliSense 类型提示:
你也可以右键点击组件名,选择
转到类型定义
, 查看组件的所有属性声明:上图的 type 属性的类型是枚举字符串,在输入时,你可以在空双括号中按下 vsCode 的 “触发提示” 快捷键(具体快捷键因不同系统操作系统和不同设置而异,请到编辑器的 “首选项->设置快捷方式” 处查看,该功能很实用):
对现有组件库进行双向数据绑定
很多时候,我们会使用 react 视图组件库来开发应用,如 ant.design、 material-ui 等,pastate 为这些现有的视图组件提供两个数据双向绑定方法!下面我们以 ant.design 的 Rate 星级评分组件为例进行介绍。
使用 Bind 高阶组件
你可以使用 pastate 提供的 Bind 组件去包围一个原始的视图组件,实现双向数据绑定。
我们先简单地安装 ant.design 组件库:$ npm install antd --save
或$ yarn add antd
,引入 Rate 组件,并使用 Bind 组件进行包装,实现双向数据绑定:import { ..., Bind } from 'pastate'; import Rate from 'antd/lib/rate'; import 'antd/lib/rate/style/css'; // 或经过简单配置后,使用 import { Rate } from 'antd', 详见 ant.design 文档 ... // 我们使用 state.basicInfo.age 数据进行演示 class BasicInfoView extends PureComponent { ... render() { /** @type {initState['basicInfo']} */ let state = this.props.state; return ( <p style={{ padding: 10, margin: 10 }}> ... <p> 年龄(Bind): <Bind value={state.age} > <Rate /> </Bind> </p> ... </p> ) } }
我们使用 Bind 组件对 Rate 组件进行包装,并把本来需要传递给 Rate 组件的 value 值传递通过 Bind 组件进行传递,这样就实现了双向数据绑定!如果我们要传递其他属性值给 Rate, 可以不通过 Bind 直接传递给 Rate,如下:
... <Bind value={state.age} > <Rate count={10} /> {/* 根据 ant design 文档, count 属性指定采用 n 级评分 */} </Bind> ...
这样我们就实现了对 Rate 进行双向数据绑定:
你可以通过点击 Rate 组件的星星或点击
descrease age
,increase age
按钮对年龄值进行改变,可以发现当通过按钮更新数据时,Rate 组件可以正确响应。而且 Bind 是一个关于 value 的纯组件,当其他无关数据发生改变时,Bind 元素不会发生多余的渲染动作。Bind 元素还有两个可选的属性:
valueProp: 指定被包装的组件接收数据的属性名,默认是
value
, 绝大多数组件也是用value
,因此无需指定该值。如果被包装的组件使用的是checked
或其他属性名接收数据值,那么请把 Bind 元素的 valueProp 设为对应的checked
或其他属性名。afterChange: 当组件绑定的值通过该组件发生改变后,会调用该函数,该函数的签名为
(newValue) => void
。当绑定的属性值不是通过该组件发生改变时,afterChange 函数不会被调用。
使用 makeBindable 函数
你也可以使用
makeBindable(RawComponent, valueProp = 'value')
函数生成一个可以复用的可绑定组件:import { ..., makeBindable } from 'pastate'; ... // 使用 makeBindable 生成对应的可以绑定数据的 Rate 组件 const MyRate = makeBindable(Rate) class BasicInfoView extends PureComponent { ... render() { /** @type {initState['basicInfo']} */ let state = this.props.state; return ( <p style={{ padding: 10, margin: 10 }}> ... <p> 年龄(makeBindable): <MyRate count={10} value={state.age}/> </p> ... </p> ) } }
你可以通过 makeBindable 函数的第二个参数指定 valueProp 值,如
const MyCheckbox = makeBindable(Checkbox, 'checked')
, 同样,你可以通过新组件的 afterChange 属性去响应组件值更新后的个性化操作。对于绑定的值为空的情况
无论使用 pastate 的表单输入组件还是包装现有的组件库,对于组件绑定的数据值,不支持被设为 null 值 或 undefind 值。通常情况下,我们不会有这种需求。如果需要实现表单的“未选择”状态, 我们一般通过设置一个默认值且不可选的 default 值来代替。例如有个表单需要选择性别,并且需要一个未选择的状态,这样使用一个 RadioGroup 组件来实现:
let initState = { sex: '' // 用字符串表示性别,并设置为选择状态是的值为空字符串 '' 或 'default' } const sexOptions = ['boy', 'girl'] // 只包含目标值 ... render(){ let state = this.props.state; return <RadioGroup options={sexOptions} value={state.sex} /> } ...
如果你的需求场景一定要用到 null 或 undefined 值,欢迎在 issues 中分享。 Pastate 能实现绑定的值支持空值,但如果这个需求只有在非常特殊的情况下才用到,我们就暂不把它默认实现在 pastate 库中,因为这会增加计算量,你可以自行实现这个特殊组件的数据绑定逻辑。
下一章,我们来看看 pastate 应用如何进行模块化。
相关推荐:
以上是Pastate.js 響應式 react 框架之表單渲染與操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中