Pastate.js 響應式框架之數組渲染與操作
這篇文章給大家分享的內容是關於Pastate.js 響應式框架之數組渲染與操作 ,有著一定的參考價值,有需要的朋友可以參考一下
這是Pastate.js 響應式react state 管理框架系列教學的第三章,歡迎關注,持續更新。
這一章讓我們來看看在 pastate 中如何渲染和處理 state 中的陣列。
渲染數組
首先我們更新一下state 的結構:
const initState = { basicInfo: ..., address: ..., pets: [{ id:'id01', name: 'Kitty', age: 2 }] }
我們定義了一個有物件元素構成的陣列initState.pets, 且該陣列有一個初始元素。
接著,我們定義相關元件來顯示pets 的值:
class PetsView extends PureComponent { render() { /** @type {initState['pets']} */ let state = this.props.state; return ( <p style={{ padding: 10, margin: 10 }}> <p><strong>My pets:</strong></p> {state.map(pet => <PetView state={pet} key={pet.id}/>)} </p> ) } }
class PetView extends PureComponent { render() { /** @type {initState['pets'][0]} */ let state = this.props.state; return ( <p> <li> {state.name}: {state.age} years old.</li> </p> ) } }
這裡定義了兩個元件,第一個是PetsView,用來顯示pets 陣列; 第二個是PetView,用來顯示pet 元素。
接下來把 PetsView 元件放入 AppView 元件中顯示:
... class AppView extends PureComponent { render() { /** @type {initState} */ let state = this.props.state; return ( <p style={{ padding: 10, margin: 10, display: "inline-block" }}> <BasicInfoView state={state.basicInfo} /> <AddressView state={state.address} /> <PetsView state={state.pets} /> </p> ) } } ...
完成!我們成功渲染了一個數組對象,這與用原生react 渲染數組的模式一樣,頁面結果如下:
修改數組
首先,我們想要新增或減少陣列元素,這用pasate 實作起來非常簡單。受 vue.js 啟發,pastate 對 store.state 的陣列節點的以下7個 陣列變異方法 都進行了加強,你可以直接呼叫這些陣列函數,pastate 會自動觸發視圖的更新。這7 個陣列變異方法如下
push()
pop()
shift()
#unshift()
##splice()
sort()
reverse( )
class PetsView extends PureComponent { pushPet(){ state.pets.push({ id: Date.now() + '', name: 'Puppy', age: 1 }) } popPet(){ state.pets.pop() } render() { /** @type {initState['pets']} */ let state = this.props.state; return ( <p style={{ padding: 10, margin: 10 }}> <p><strong>My pets:</strong></p> {state.map(pet => <PetView state={pet} key={pet.id}/>)} <p> <button onClick={this.pushPet}>push pet</button> <button onClick={this.popPet}>pop pet</button> </p> </p> ) } }
元素類型,並註解這個陣列節點的元素為該型別:
const initState = { ... /** @type {[pet]} */ pets: [] } const pet = { id: 'id01', name: 'Kitty', age: 2 }
/**@type {數組 。
單一實例元件,是指元件只被使用一次;而我們可以到 PetView 被用於顯示數組元素,會被多次使用。我們把這類在多處被使用的元件稱為多重實例元件。多實例元件內部動作的處理邏輯由元件實例的具體位置而定,與單一實例元件的處理模式有差別,我們來看看。
我們試著製作一個每個寵物視圖中加入兩個按鈕來調整寵物的年齡,我們用兩種傳統方案和pastate方案分別實現:react 傳統方案傳統方案1:父元件處理
父元件向子元件傳遞綁定index的處理函數:這個模式是把子元件的動作處理邏輯實作在父元件中,然後父元件把動作綁定對應的index 後傳遞給子元件
class PetsView extends PureComponent { ... addAge(index){ state.pets[index].age += 1 } reduceAge(index){ state.pets[index].age -= 1 } render() { /** @type {initState['pets']} */ let state = this.props.state; return ( <p style={{ padding: 10, margin: 10 }}> ... { state.map((pet, index) => <PetView state={pet} key={pet.id} addAge={() => this.addAge(index)} // 绑定 index 值,传递给子组件 reduceAge={() => this.reduceAge(index)} // 绑定 index 值,传递给子组件 />) } ... </p> ) } }
class PetView extends PureComponent { render() { /** @type {initState['pets'][0]} */ let state = this.props.state; return ( <p > <li> {state.name}: <button onClick={this.props.reduceAge}> - </button> {/* 使用已绑定 index 值得动作处理函数 */} {state.age} <button onClick={this.props.addAge}> + </button> {/* 使用已绑定 index 值得动作处理函数 */} years old. </li> </p> ) } }
push pet 增加一些元素後,再點擊
或
- 按鈕看看元件重新渲染的情況:
传统方案2:子组件结合 index 实现
父组件向子组件传递 index 值:这种模式是父组件向子组件传递 index 值,并在子组件内部实现自身的事件处理逻辑,如下:
class PetsView extends PureComponent { ... render() { ... return ( <p style={{ padding: 10, margin: 10 }}> ... { state.map((pet, index) => <PetView state={pet} key={pet.id} index={index} // 直接把 index 值传递给子组件 />) } ... </p> ) } }
class PetView extends PureComponent { // 在子组件实现动作逻辑 // 调用时传递 index addAge(index){ state.pets[index].age += 1 } // 或函数自行从 props 获取 index reduceAge = () => { // 函数内部使用到 this 对象,使用 xxx = () => {...} 来定义组件属性更方便 state.pets[this.props.index].age -= 1 } render() { /** @type {initState['pets'][0]} */ let state = this.props.state; let index = this.props.index; return ( <p > <li> {state.name}: <button onClick={() => this.reduceAge(index)}> - </button> {/* 使用闭包传递 index 值 */} {state.age} <button onClick={this.addAge}> + </button> {/* 或让函数实现自己去获取index值 */} years old. </li> </p> ) } }
这种模式可以使子组件获取 index 并处理自身的动作逻辑,而且子组件也可以把自身所在的序号显示出来,具有较强的灵活性。我们再来看看其当元素内部 state 改变时,组件的重新渲染情况:
我们发现,数组元素组件可以很好地按需渲染,在渲染数组元素的情况下这种方法具有较高的运行效率。
但是,由于元素组件内部操作函数绑定了唯一位置的 state 操作逻辑,如addAge(index){ state.pets[index].age += 1}
。假设我们还有 state.children
数组,数组元素的格式与 state.pets
一样, 我们要用相同的元素组件来同时显示和操作这两个数组时,这种数组渲染模式就不适用了。我们可以用第1种方案实现这种情况的需求,但第1种方案在渲染效率上不是很完美。
pastate 数组元素操作方案
Pastate 的 imState 的每个节点本身带有节点位置的信息和 store 归宿信息,我们可以利用这一点来操作数组元素!
pastate 方案1:获取对于的响应式节点
我们使用 getResponsiveState 函数获取 imState 对于的响应式 state,如下:
class PetsView extends PureComponent { ... render() { ... return ( <p style={{ padding: 10, margin: 10 }}> ... { state.map((pet, index) => <PetView state={pet} key={pet.id} {/* 注意,这里无需传递 index 值,除非要在子组件中有其他用途*/} />) } ... </p> ) } }
import {..., getResponsiveState } from 'pastate' class PetView extends PureComponent { addAge = () => { /** @type {initState['pets'][0]} */ let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 获取响应式 state 节点 pet.age += 1 } reduceAge = () => { /** @type {initState['pets'][0]} */ let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 获取响应式 state 节点 pet.age -= 1 } render() { /** @type {initState['pets'][0]} */ let state = this.props.state; return ( <p > <li> {state.name}: <button onClick={this.reduceAge}> - </button> {state.age} <button onClick={this.addAge}> + </button> years old. </li> </p> ) } }
我们可以看到,子组件通过 getResponsiveState 获取到当前的 props.state 对应的响应式 state,从而可以直接对 state 进行复制修改,你无需知道 props.state 究竟在 store.state 的什么节点上! 这种模式使得复用组件可以在多个不同挂载位置的数组中使用,而且可以保证很好的渲染性能:
pastate 方案2:使用 imState 操作函数
Pastate 提供个三个直接操作 imState 的函数,分别为 set
, merge
, update
。我们来演示用这些操作函数来代替 getResponsiveState
实现上面操作宠物年龄的功能:
import {..., set, merge, update } from 'pastate' class PetView extends PureComponent { addAge = () => { set(this.props.state.age, this.props.state.age + 1); } reduceAge = () => { merge(this.props.state, { age: this.props.state.age - 1 }); } reduceAge_1 = () => { update(this.props.state.age, a => a - 1); } ... }
可见,这种 imState 操作函数的模式也非常简单!
使用 pastate 数组元素操作方案的注意事项:当操作的 state 节点的值为 null 或 undefined 时, 只能使用 merge
函数把新值 merge 到父节点中,不可以使用 getResponsiveState
,set
或 update
。我们在设计 state 结构时,应尽量避免使用绝对空值,我们完全可以用 ''
, []
等代替绝对空值。
下一章,我们来看看如何在 pastate 中渲染和处理表单元素。
这是 Pastate.js 响应式 react state 管理框架系列教程的第三章,欢迎关注,持续更新。
这一章我们来看看在 pastate 中如何渲染和处理 state 中的数组。
相关推荐:
Pastate.js 之响应式 react state 管理框架
以上是Pastate.js 響應式框架之數組渲染與操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

1.首先在酷家樂中開啟要渲染的設計方案。 2、然後在渲染選單下開啟俯視圖渲染。 3.接著在俯視圖渲染介面中點選參數設定中的正交。 4.最後調整好模型角度即可點選立即渲染,渲染正交俯視圖。

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。
