React中的事件总线?

时间:2018-11-16 00:31:47

标签: javascript reactjs

我主要使用Vue,最近才开始使用React。到目前为止,我一直都很喜欢它,并且在很多方面都与Vue非常相似,这使得学习起来更加容易。

现在,让我们考虑两个同级组件。当第二个部件发生故障时,我想触发第一个部件的故障。在Vue中,您可以仅绑定window.bus = new Vue,然后发出一个组件bus.$emit('event')并绑定到第二个组件mounted()的{​​{1}}中。

如何在React中实现呢?

5 个答案:

答案 0 :(得分:2)

父组件可以管理state和子组件通过props传递时使用的方法。

下面的示例增加一个计数。 SibOne显示计数,而SibTwo中的按钮增加计数。

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        };
    }
    incrementCount = () => {
        this.setState({
            count: this.state.count + 1
        });
    }
    render() {
        return (
            <div className="App">
                <SibOne count={this.state.count}/>
                <SibTwo incrementCount={this.incrementCount}/>
            </div>
        );
    }
}

const SibOne = props => <div>Count: {props.count}</div>;

const SibTwo = props => (
    <button onClick={props.incrementCount}>
        Increment Count
    </button>
);

演示:https://codesandbox.io/s/zqp9wj2n63

有关组件和道具的更多信息:https://reactjs.org/docs/components-and-props.html

答案 1 :(得分:1)

如果有两个同级组件,则将状态保留在父级组件中,并将该状态作为对两个同级的支持:

class ParentComponent extends Component {
  state = {
   specialProp: "bar"
  }

  changeProp = () => {
   // this.setState.. 
  }
  render() {
    return (
      <div>
        <FirstSibling specialProp={this.state.specialProp} />
        <SecondSibling changeProp={this.changeProp} specialProp={this.state.specialProp} />
      </div>
    );
  }
}

答案 2 :(得分:1)

对于那些仍在搜索的人,请看这篇文章:https://www.pluralsight.com/guides/how-to-communicate-between-independent-components-in-reactjs

解决方案使用:

document.addEventListener for $on;

document.dispatchEvent for $emit;

document.removeEventListener for $off;

在我的用例中,我有一个包含刷新按钮的组件,该按钮会触发其他组件中的数据刷新。

我做了文章中介绍的一切。如果您将 React 与 Functional Components 一起使用,您可能需要使用以下 useEffect:

  useEffect(() => {
    // The component might unmount when the request is in progress.
    // Because of this an error will appear when we'll try to 'setData'.
    let isMounted = true

    const getData = () => {
      reqData(db, path)
        .then(result => {
          if (isMounted) {
            setData(result) // This is a useState
          }
        })
    }

    eventBus.on('refreshData', (data) => {
      getData()
    })

    getData()

    return () => {
      isMounted = false
      eventBus.remove('refreshData')
    }

    // Do not change the end of this useEffect. Keep it as it is. It simulates componentDidMount.
    // eslint-disable-next-line
  }, [])

答案 3 :(得分:0)

class _EventBus {

    constructor() {
        this.bus = {};
    }

    $on(id, callback) {
        this.bus[id] = callback;
    }

    $emit(id, ...variaveis) {
        this.bus[id](...variaveis);
    }
}

export const EventBus = new _EventBus();

答案 4 :(得分:0)

rxjs是您可以探索的另一种选择。检查它们在提供可观察的基于事件的程序时是否对您有帮助。它也正在做类似Eventbus在vuejs中做的事情。