Pastate.js 応答フレームワークの配列レンダリングと操作
この記事で共有する内容は、Paste.js レスポンシブ フレームワークの配列レンダリングと操作に関するもので、必要な友人は参考にしてください。これは Pastate.js レスポンシブな反応状態管理フレームワークです。シリーズのチュートリアルの第 3 章、注目して更新を続けてください。
この章では、ペースト状態の配列をレンダリングして処理する方法を見てみましょう。
配列のレンダリング
まず状態の構造を更新します:
const initState = { basicInfo: ..., address: ..., pets: [{ id:'id01', name: 'Kitty', age: 2 }] }
オブジェクト要素で構成される配列 initState.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> ) } }
ここでは 2 つのコンポーネントが定義されています。1 つ目は PetsView で、ペット配列の表示に使用されます。2 つ目は PetView で、ペット要素の表示に使用されます。
次に、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 Simple を使用すると非常に簡単に実現できます。 vue.js からインスピレーションを受け、paste は、store.state の配列ノードの次の 7 つの
配列変更メソッドを強化しました。これらの配列関数を直接呼び出すことができ、paste はビューの更新を自動的にトリガーします。これら 7 つの配列変更メソッドは次のとおりです
pop()
shift()
unshift()
splice()
sort()
reverse()
push()
push()
我们来尝试使用 push 和 pop 来更新数组:
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> ) } }
非常容易!我们还添加了两个按钮并指定了点击处理函数,运行体验一下:
打开 react dev tools 的 Highlight Updates 选项,并点击 push 或 pop 按钮,可以观察到视图更新情况如我们所愿:
空初始数组与编辑器 intelliSence
通常情况下,数组节点的初始值是空的。为了实现编辑器 intelliSence, 我们可以在外面定义一个元素类型,并注释这个数组节点的元素为该类型:
const initState = { ... /** @type {[pet]} */ pets: [] } const pet = { id: 'id01', name: 'Kitty', age: 2 }
你也可以使用泛型的格式来定义数组类型: /** @type {Array<pet>} */
。
多实例组件的内部动作处理
上一章我们提到了单实例组件,是指组件只被使用一次;而我们可以到 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> ) } }
这种模式可以把动作的处理统一在一个组件层级,如果多实例组件的视图含义不明确、具有通用性,如自己封装的 Button 组件等,使用这种动作处理模式是最好的。但是如果多实例组件的含义明显、不具有通用性,特别是用于显示数组元素的情况下,使用这种模式会引发多余的渲染过程。
打开 react dev tools 的 Highlight Updates 选项,点击几次 push pet
增加一些元素后,再点击 +
或 -
pop()
shift ( )
unshift()
🎜splice()
🎜🎜🎜 sort ()
🎜🎜🎜reverse()
🎜🎜プッシュとポップを使って配列を更新してみましょう: 🎜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> ) } }
/** @type {配列<pet>}*/
。 🎜🎜マルチインスタンスコンポーネントの内部アクション処理🎜🎜前の章で説明しました🎜単一インスタンスコンポーネント🎜。これは、コンポーネントが一度だけ使用されることを意味し、PetView は配列要素を表示するために使用されることがわかります。複数回使用されました。このように複数の場所で使用されるコンポーネントを🎜マルチインスタンス コンポーネント🎜と呼びます。マルチインスタンス コンポーネントの内部アクションの処理ロジックは、コンポーネント インスタンスの特定の場所によって決まります。これは、単一インスタンス コンポーネントの処理モードとは異なります。見てみましょう。 🎜🎜ペットの年齢を調整するために各ペット ビューに 2 つのボタンを追加する方法を作成しようとします。2 つの従来のソリューションとペースト ソリューションをそれぞれ使用して実装します。 🎜従来のソリューションに反応
従来の解決策 1: 親コンポーネントの処理
🎜🎜親コンポーネントは、バインディング インデックス処理関数を子コンポーネントに渡します🎜: このモードでは、子コンポーネントのアクション処理ロジックを親コンポーネントに実装し、次に親コンポーネントを実装します。それに応じてアクションをバインドします。その後、インデックスがサブコンポーネントに渡されます🎜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> ) } }
push pet
を数回クリックし、いくつかの要素を追加した後、+
または -
ボタンをクリックします。コンポーネントの再レンダリングの状況を確認するには: 🎜🎜🎜🎜🎜🎜🎜 特定の配列要素 (pet[x].age) 内の値のみを変更すると、他の配列要素も再レンダリングされることがわかります。これは、Pet.props.addAge と Pet.props.reduceAge が親コンポーネント PetsView がレンダリングされるたびに再生成される匿名オブジェクトであるため、PureComponent はこれを使用してコンポーネントが依存するデータが更新されたと判断し、re をトリガーします。 -レンダリング。この問題は、React.Component とカスタム shouldComponentUpdate ライフサイクル関数を使用することで手動で解決できますが、親コンポーネント PetsView がレンダリングされるたびに匿名サブコンポーネント プロパティ値が再生成され、これによりコンピューティング リソースも消費されます。 🎜传统方案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 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

1. まず、Kijiale でレンダリングするデザインプランを開きます。 2. 次に、レンダリング メニューでトップ ビュー レンダリングを開きます。 3. 次に、トップ ビュー レンダリング インターフェイスのパラメーター設定で [直交] をクリックします。 4. 最後に、モデルの角度を調整した後、[今すぐレンダリング]をクリックして直交上面ビューをレンダリングします。

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用
