H
H
Hazrat Hajikerimov2017-02-07 01:29:43
React
Hazrat Hajikerimov, 2017-02-07 01:29:43

How to pass data to a component from a container in a router?

Perhaps I didn’t formulate the question correctly, now I’ll explain on my fingers what I mean:
Here is my router:

import React from 'react'
import { Route, IndexRedirect } from 'react-router'

import App from './containers/App'
import Publication from './containers/Publication';

import NotFound from './components/NotFound'
import PublicationList from './components/PublicationList';
import PublicationForm from './components/PublicationForm';
import PublicationSetting from './components/PublicationSetting';

export const routes = (
  <div>
    <Route path='/' component={App}>
      <Route path='publications' component={Publication}>
          <IndexRedirect to='list' />
          <Route path='list' component={PublicationList} />
          <Route path='form' component={PublicationForm} />
          <Route path='setting' component={PublicationSetting} />
      </Route>
      <Route path='*' component={NotFound} />
    </Route>
  </div>
)

Focus on the "Publication" container and the "PublicationList" component.
The user went to the url /publications/list, first worked out the "Publication" container naturally, where this.props.childrenthe "PublicationList" child component is passed to him.
Naturally, in the "Publication" in the render there is {this.props.children}
Now the question is, when the "Publication" container is initialized, it receives the initial state, How to transfer the necessary data from the state to the component {this.props.children}(PublicationList)?
Of course, there are components inside "Publication" that can be passed state directly to props: and everything works, but what about dynamic components that are connected depending on the url?
I have not yet specified whether it is possible to add routes to the "Publication" container, but it seems to me that this will lead to chaos, since it is convenient when all the routes are in one file and you know which component / container the application responds to.
In general, something like this, please poke, because I did not find the information.
UPD:
Do you really have to transfer components into containers and create your own reducer, action, constants for each of them? it will spawn so many files.
How do you solve this issue?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Aves, 2017-02-07
@Aves

https://facebook.github.io/react/docs/context can be used.

class Publication extends React.Component {
  state = {
    list: []
  };
  componentDidMount() {
    this.timer = setInterval(() => {
      this.setState({list: [...this.state.list, new Date().toString()]});
    }, 10000);
  }
  componentWillUnmount() {
    clearInterval(this.timer);
  }
  static childContextTypes = {
    list: React.PropTypes.array
  };
  getChildContext() {
    return {
      list: this.state.list
    };
  }
  render() {
    return (
      <div>
        <h4>Publication</h4>
        {this.props.children}
      </div>
    );
  }
}

const PublicationList = (props, context) => (
  <ul>
    {context.list.map(e => <li key={e}>{e}</li>)}
  </ul>
);
PublicationList.contextTypes = {list: React.PropTypes.array};

In general, I don’t see what is the difficulty in using redux, and why
for each of them create your own reducer, action, constants
Simple enough
export connect(state => ({list: state.publication.list}))(PublicationList)

K
kostik, 2017-02-07
@kostiknoir

method #1 the parent component
explicitly knows what the child component needs and then the parent component explicitly passes the necessary values ​​through props
One of the main disadvantages: in each parent component, you need to take into account the requirements of all child components at all lower levels use something from its props and state (i.e. from the props and state of the parent component). Therefore, the parent component explicitly passes its state and props to the child element using props Minus #1 - see method #1 Minus #2 - the state of this parent component becomes public. What is not always good way #3
the data that is needed for different components is taken out to the global scope (redux, flux, mobx, etc.).
In this case, the parent component updates some part of the public data.
Other components that are interested in this data subscribe to notifications of changes to this data
Minus - an additional level of abstraction
But solves the shortcomings of the previous options
Which is better... Depends on the situation

I
Ivan, 2017-02-07
@LiguidCool

Well, Redux is just for that?
upd. v.2

  1. Read how modules are arranged in React without a router (there are a lot of examples). Let's say. there is App, Users is connected in it . There, in turn, there are 2 classes Users and User . Moreover, the second can also be in a separate file. This somewhat helps to unload the App. This is not required, but it abstracts the App from the User. The application does not need to know about the user, only about their list.
  2. Take a look at the example in the docs. Just a very similar implementation as yours. User is a child component of Users :
    componentDidMount() {
        this.setState({
          // route components are rendered with useful information, like URL params
          user: findUserById(this.props.params.userId)
        })

    If you have a "stupid" component, then no one bothers you to immediately render this.props.params. bla bla

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question