在同一层级子组件之间共享存储更改事件

Posted

技术标签:

【中文标题】在同一层级子组件之间共享存储更改事件【英文标题】:Sharing store change event between same hierarchical level child components 【发布时间】:2018-12-10 02:38:12 【问题描述】:

我正在开发一个简单的 React JS 应用程序用于学习目的。几天前我刚开始学习 React JS。现在,我遇到了 Flux Store 的问题。我需要在同一层级的两个子组件之间共享更改事件。

我有父组件,名为 TodoComponent,定义如下

//Create
class TodoComponent extends React.Component
    constructor(props)
        super(props)

    


    render()

        return (
            <div>
                <div>
                <ListComponent />
                </div>
                <AddItemComponent />
            </div>
        )
    

它有两个名为 ListComponent 和 AddItemComponent 的子组件。此外,我有一个具有此定义的商店。

import  EventEmitter  from 'events';

class DataStore extends EventEmitter

    constructor()
    
        super();
        this.todos = [
            "Eat",
            "Sleep",
            "Die",
            "Shower"
        ];
    

    getAll()
        return this.todos;
    

    addItem(newItem)
    
        this.todos.push(newItem);
        this.emit("change")
    



const dataStore = new DataStore;

export default dataStore;

它具有向数组中添加新项目的功能和获取数组的功能。

这是显示来自 DataStore 通量存储的项目数组的 ListComponent。

import React from 'react';
import TodoItem from './TodoItem';
import DataStore from './data.store';

class ListComponent extends React.Component
    constructor(props)
    
        super(props)
        this.state =  todos : DataStore.getAll() ;
    

    componentWillMount()
        DataStore.on('change', () => 
            //do somethif
            this.state =  todos : DataStore.getAll() ;
        )
    

    render()
    
        var deleteItem = (item) => 
            this.deleteItem(item);
        
        var editItem = (item) => 
            this.editItem(item);
        

        var addItem = (newItem) => 
            this.addItem(newItem);
        
        var todos = this.state.todos.map((item, index) => 
            return (
                <TodoItem item=item addItem=addItem.bind(this) deleteItem=deleteItem editItem=editItem />
            )
        );

        return (
            <ul>
                todos
            </ul>
        )
    

    deleteItem(item)
    
        this.setState( todos: this.state.todos.filter((listItem, index) => 
            return listItem !== item; 
        ) );
    

    editItem(item)
    
        alert(item)
    

    addItem(newItem)
    
        DataStore.addItem(newItem);
    


module.exports = ListComponent;

它正在更新 DataStore 存储的更改事件中的项目。但我没有在 ListComponent 中调用 addItem 函数。我在 AddItemComponent 中调用它。 这是 AddItemComponent 的定义。

import React from 'react';
import DataStore from './data.store';

class AddItemComponent extends React.Component
    constructor(props)
    
        super(props)

    

    render()
    
        return (
            <form id="form-todo" onSubmit=this.addItem.bind(this) action="post">
                <input type='text' ref="newItem" />
                <button>ADD</button>
            </form>
        );
    

    addItem(e)
    
        e.preventDefault();
        DataStore.addItem(this.refs.newItem.value);
    


module.exports = AddItemComponent;  

但是当我在AddItemComponent中触发addItem函数时,ListComponent中DataStore的change事件并没有触发。那么,如何在同层级的两个组件之间同步 Flux Store 的 change 事件呢?

我能想到的解决方案是在 TodoComponent(父组件)中拥有 DataStore,并将数据和函数作为 props 发送给子组件。我认为,这样代码会变得有点混乱。这是唯一的解决方案吗?

【问题讨论】:

【参考方案1】:

欢迎来到反应!我重新创建了您的示例,并且您的“更改”事件在ListComponent 中触发,但是要更新组件中的状态,您应该使用this.setState(changes) 而不是this.state = changes。仅在构造函数中使用this.state = 来设置初始状态。 setState 方法正确地流过 React 生命周期,并导致组件使用新状态重新渲染。有一个关于 React 的状态和生命周期钩子的官方指南here。

【讨论】:

以上是关于在同一层级子组件之间共享存储更改事件的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在单独的 Angular(子)项目之间共享 NGXS 存储?

Vue3组件(18)组件间传值/共享的方法的汇总

Vuex

如何在 Monorepo 中的 VueJS 项目之间共享组件

源码分析vuex如何维护多个组件的数据共享

被父组件移除的子组件仍然获得存储更改事件