¿Como llamar una función de un componente desde otro componente?

publicado por: Anonymous

Tengo el siguiente problema, necesito llamar una función desde un componente al otro.

Tengo el componente X donde se verifica cuando el usuario hace scroll hasta el final del sitio, cuando esto pasa puedes hacer una acción sea un alert, un setState o lo que sea.

  container.onscroll = function () {
  let height = this.clientHeight;
  let scrollHeight = this.scrollHeight;
  let scrollTop = this.scrollTop;

  if (height + scrollTop === scrollHeight) {
     _this.setState({ display: 'loader'});
      funcionupdate() <--
     setTimeout(function(){  _this.setState({ display: 'hidden'}); }, 2000);
    }
}

Por otro lado el componente Y, en el cual hay una función update().

Como puedo ejecutar la función update() del componente Y desde el componente X?

solución

Puedes hacerlo por Context, para lo cual el contenedor padre debe contener la función a ejecutar cuando el scroll llega hacia abajo. En caso de comunicar componentes que ni siquiera son hermanos, sería muy complejo de este modo. La mejor opción para mantener las cosas simples es implementar en la aplicación el patrón de diseño Observer. De esta manera puedes establecer comunicación entre cualquier grupo de componentes (no solo dos). Puedes usar librerías para esto como Postal.js, PubSub.js, MicroEvent.js o EventEmitter2.

Ejemplo

_x000D_

_x000D_

class Sidebar extends React.Component {_x000D_
  constructor (props) {_x000D_
    super(props);_x000D_
    this.state = {_x000D_
      message: ''_x000D_
    };_x000D_
    this.channel = null;_x000D_
  }_x000D_
  _x000D_
  render () {_x000D_
    return (_x000D_
      <aside className="sidebar">_x000D_
        { this.state.message }_x000D_
      </aside>_x000D_
    );_x000D_
  }_x000D_
  _x000D_
  componentDidMount () {_x000D_
    this.channel = postal.channel();_x000D_
    this.channel.subscribe('scroll.end', (data) => {_x000D_
      console.info('Received data:', data);_x000D_
      this.onScrollContentEnd();_x000D_
    });_x000D_
  }_x000D_
  _x000D_
  onScrollContentEnd () {_x000D_
    // hacer algo_x000D_
    this.setState({_x000D_
      message: 'Scroll End'_x000D_
    });_x000D_
  }_x000D_
}_x000D_
_x000D_
class Content extends React.Component {_x000D_
  constructor (props) {_x000D_
    super(props);_x000D_
    this.channel = null;_x000D_
  }_x000D_
  _x000D_
  render () {_x000D_
    return (_x000D_
      <article className="content" onScroll={this.onscroll.bind(this)}>_x000D_
        <div id="big"></div>_x000D_
      </article>_x000D_
    );_x000D_
  }_x000D_
  _x000D_
  componentDidMount () {_x000D_
    this.channel = postal.channel();_x000D_
  }_x000D_
  _x000D_
  onscroll (e) {_x000D_
    let el = e.target;_x000D_
    let height = el.clientHeight;_x000D_
    let scrollHeight = el.scrollHeight;_x000D_
    let scrollTop = el.scrollTop;_x000D_
_x000D_
    if (height + scrollTop === scrollHeight) {_x000D_
      // puedes enviar datos opcionales ;)_x000D_
      this.channel.publish('scroll.end', {_x000D_
        someData: 'xyz123'_x000D_
      });_x000D_
    }_x000D_
  }_x000D_
}_x000D_
_x000D_
class Container extends React.Component {_x000D_
  render () {_x000D_
    return (_x000D_
      <section ref="el" className="container">_x000D_
        <Sidebar/>_x000D_
        <Content/>_x000D_
      </section>_x000D_
    )_x000D_
  }_x000D_
}_x000D_
_x000D_
ReactDOM.render(<Container/>, document.getElementById('app'));

_x000D_

*,_x000D_
*:before,_x000D_
*:after {_x000D_
  box-sizing: border-box;_x000D_
  margin: 0;_x000D_
  padding: 0;_x000D_
}_x000D_
_x000D_
.container {_x000D_
  display: flex;_x000D_
  height: 100vh;_x000D_
  overflow: hidden;_x000D_
  width: 100%;_x000D_
}_x000D_
_x000D_
.sidebar {_x000D_
  background-color: #f39c12;_x000D_
  color: #fff;_x000D_
  flex: 0 0 240px;_x000D_
  font-family: 'Segoe UI', 'Ubuntu';_x000D_
  line-height: 100vh;_x000D_
  text-align: center;_x000D_
}_x000D_
_x000D_
.content {_x000D_
  background-color: #2980b9;_x000D_
  flex: 1;_x000D_
  overflow: auto;_x000D_
}_x000D_
_x000D_
#big {_x000D_
  height: 1200px;_x000D_
  margin: 40px auto;_x000D_
  width: 200px;_x000D_
}

_x000D_

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/postal.js/2.0.5/postal.min.js"></script>_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>_x000D_
_x000D_
<div id="app"></div>

_x000D_

_x000D_

_x000D_


Nota: el ejemplo usa la librería Postal.js que a su vez depende de lodash.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *