Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing data between components in React

I'm developing an app using Meteor and React as view engine

Consider this diagram:

React hide component from another example

I need to change C2 component state when C4 button click event is fired. Since they don't have a direct relationship i cannot access to C2 state directly from C4.

Another example would be submit a form from a Component and get the data (value of input fields) declared in another Component.

I know there are some possible hacks to solve this problem (e.g. Meteor Session, pass data through each component, flux-based Action/Dispatcher).

React docs recommends to use event/subscribe system (flux is a possible solution, but flux is much more that this...) Communicate Between Components

Redux is another possibility (i'm a bit worried about the fact that for large applications if i have a lot of actions, the combined-reducers-function will explode and also about the absence of an action-specific subscribe system - as far as i know all the listener will be executed when dispatch an action - i'm new in redux maybe i'm wrong)

Flux or Redux are valid pattern and satisfy a need bigger than mine, i have already Meteor for that kind of work. My only need is to access the component state inside another...

I need a scalable solution for medium/large applications with a high number of component views

What's the "right" way to solve that problem?


Update:

recently I gave redux a chance and it seems to do the work (it is really awesome and well supported), so if you are in the same situations check React + Redux: submit multi-component form

like image 861
luk_z Avatar asked Jun 21 '16 15:06

luk_z


2 Answers

You can use any publish/subscribe events library and then make your components listen to any event you need.

For example:

import React from 'react'
import 'events' from 'eventPublishSubscribeLibrary'

class Component2 extends React.Component {
  constructor (props) {
    super(props)
    this.toggleVisibility = this.toogleVisibility.bind(this)
    this.state = {
      visible = true
    }
  }
  componentDidMount () {
    events.subscribe('clicked-button', this.toogleVisibility)
  }
  toogleVisibility () {
    this.setState({
      visible: !this.state.visible
    })
  }
  render () {
    return visible && (
      <div>content</div>
    )
  }
}

const Component4 = () => (
  <button onClick={events.publish('clicked-button')}>Toggle Visibility</button>
)

You can find in this post by davidwalsh a simple implementation for a Pub/Sub JavaScript Object. Or you can search in npm for some other library.

the "right" way

This is the most simple implementation I can think of and for small projects it is a quick an easy solution that should work.

Anyway, as far as the project will grow a bit you will start to have a lot of actions/reactions between your components. With every new component you'll add it'll get more complicated to track all of these relations between all your components. Here is where it comes handy to have the global state of your application stored in one single place, and that is one of the three principles that redux is based on: the single source of truth.

like image 177
Eloy Pineda Avatar answered Oct 20 '22 19:10

Eloy Pineda


I think it's perfect time for you to introduce some state to your app. Try Redux, it's awesome.

like image 23
Alexander Davydov Avatar answered Oct 20 '22 19:10

Alexander Davydov