検索
ホームページウェブフロントエンドjsチュートリアル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[&#39;pets&#39;][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 で配列をレンダリングするパターンと同じ、配列オブジェクトを正常にレンダリングしました。ページの結果は次のとおりです。

Pastate.js 応答フレームワークの配列レンダリングと操作配列を変更します

まず、配列要素を追加または削除します。これは、pasate Simple を使用すると非常に簡単に実現できます。 vue.js からインスピレーションを受け、paste は、store.state の配列ノードの次の 7 つの

配列変更メソッド

を強化しました。これらの配列関数を直接呼び出すことができ、paste はビューの更新を自動的にトリガーします。これら 7 つの配列変更メソッドは次のとおりです

    push()
  • push()

  • pop()

  • shift()

  • unshift()

  • splice()

  • sort()

  • reverse()

我们来尝试使用 push 和 pop 来更新数组:

class PetsView extends PureComponent {

    pushPet(){
        state.pets.push({
            id: Date.now() + &#39;&#39;,
            name: &#39;Puppy&#39;,
            age: 1
        })
    }

    popPet(){
        state.pets.pop()
    }

    render() {
        /** @type {initState[&#39;pets&#39;]} */
        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>
        )
    }
}

非常容易!我们还添加了两个按钮并指定了点击处理函数,运行体验一下:

Pastate.js 応答フレームワークの配列レンダリングと操作

打开 react dev tools 的 Highlight Updates 选项,并点击 push 或 pop 按钮,可以观察到视图更新情况如我们所愿:

Pastate.js 応答フレームワークの配列レンダリングと操作

空初始数组与编辑器 intelliSence

通常情况下,数组节点的初始值是空的。为了实现编辑器 intelliSence, 我们可以在外面定义一个元素类型,并注释这个数组节点的元素为该类型:

const initState = {
    ...
    /** @type {[pet]} */
    pets: []
}
const pet = {
    id: &#39;id01&#39;,
    name: &#39;Kitty&#39;,
    age: 2
}

你也可以使用泛型的格式来定义数组类型:  /** @type {Array<pet>} */</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[&#39;pets&#39;]} */
        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[&#39;pets&#39;][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 ( )Pastate.js 応答フレームワークの配列レンダリングと操作

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>
        )
    }
}
🎜とても簡単です!また、2 つのボタンを追加し、クリック処理関数を指定しました: 🎜🎜🎜Pastate.js 応答フレームワークの配列レンダリングと操作🎜🎜🎜 React dev tools の [Highlight Updates] オプションを開き、プッシュ ボタンまたはポップ ボタンをクリックします。ビューが希望どおりに更新されることがわかります: 🎜🎜🎜Pastate.js 応答フレームワークの配列レンダリングと操作🎜🎜🎜空の初期配列とエディター intelliSence🎜🎜 通常、配列ノードの初期値は空です。エディター インテリセンスを実装するには、外部で 🎜要素タイプ🎜 を定義し、この配列ノードの要素に次のタイプとして注釈を付けることができます: 🎜
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[&#39;pets&#39;][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>}*/</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 &#39;pastate&#39;

class PetView extends PureComponent {
    addAge = () => {
        /** @type {initState[&#39;pets&#39;][0]} */
        let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 获取响应式 state 节点
        pet.age += 1
    }
    reduceAge = () => {
        /** @type {initState[&#39;pets&#39;][0]} */
        let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 获取响应式 state 节点
        pet.age -= 1
    }
    render() {
        /** @type {initState[&#39;pets&#39;][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>
        )
    }
}
🎜このモードは、マルチインスタンス コンポーネントのビューの意味が不明瞭で普遍的な場合、コンポーネント レベルでアクションの処理を統合できます。カプセル化された Button コンポーネントでは、このアクションを使用します。処理モードが最適です。ただし、マルチインスタンス コンポーネントの意味が明白で普遍的ではない場合、特に配列要素の表示に使用される場合、このモードを使用すると冗長なレンダリング プロセスが発生します。 🎜🎜 React dev tools の [Highlight Updates] オプションを開き、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[&#39;pets&#39;][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 改变时,组件的重新渲染情况:

Pastate.js 応答フレームワークの配列レンダリングと操作

我们发现,数组元素组件可以很好地按需渲染,在渲染数组元素的情况下这种方法具有较高的运行效率。

但是,由于元素组件内部操作函数绑定了唯一位置的 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 &#39;pastate&#39;

class PetView extends PureComponent {
    addAge = () => {
        /** @type {initState[&#39;pets&#39;][0]} */
        let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 获取响应式 state 节点
        pet.age += 1
    }
    reduceAge = () => {
        /** @type {initState[&#39;pets&#39;][0]} */
        let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 获取响应式 state 节点
        pet.age -= 1
    }
    render() {
        /** @type {initState[&#39;pets&#39;][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.js 応答フレームワークの配列レンダリングと操作

pastate 方案2:使用 imState 操作函数

Pastate 提供个三个直接操作 imState 的函数,分别为 set, merge, update。我们来演示用这些操作函数来代替  getResponsiveState 实现上面操作宠物年龄的功能:

import {..., set, merge, update } from &#39;pastate&#39;

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 到父节点中,不可以使用  getResponsiveStatesetupdate。我们在设计 state 结构时,应尽量避免使用绝对空值,我们完全可以用 '', [] 等代替绝对空值。

下一章,我们来看看如何在 pastate 中渲染和处理表单元素。


这是 Pastate.js 响应式 react state 管理框架系列教程的第三章,欢迎关注,持续更新。

这一章我们来看看在 pastate 中如何渲染和处理 state 中的数组。

相关推荐:

Pastate.js 之响应式 react state 管理框架

Pastate.js 响应式框架之多组件应用

以上がPastate.js 応答フレームワークの配列レンダリングと操作の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター