0
votes

Hello and thank you in advance for your help. I have a problem passing props to components loaded with routes. I have a routes file with a wrapper component that loads the pages regarding the path url. On the wrapper component (Layout) I would like to pass to the children components some props. But as the children components are called with this.props.children I don't know how to pass the props. I tried many things and nothing has worked.

I have the following rotes file:

import React from 'react';
import { Route, IndexRoute } from 'react-router';
import Layout from '../components/pages/Layout.js';
import Search from '../components/pages/Search.js';
import Queue from '../components/pages/Queue.js';
import About from '../components/pages/About.js';

const routes = () =>
    <Route path="/" component={Layout}>
        <IndexRoute component={Search}></IndexRoute>
        <Route path="queue" component={Queue}></Route>
        <Route path="about" component={About}></Route>
    </Route>
export default routes;

In Layout I have:

import React from "react";

import Footer from "../common/Footer.js";
import Nav from "../common/Nav.js";
import Header from "../common/Header.js";

export default class Layout extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isSongPlaying: false,
            playingTrackId: "",
            playingList: []
        }
    }

    handleClickTrack(track) {
        this.setState({
           isSongPlaying: !this.state.isSongPlaying
        });

    }

    renderTrack(i) {
        return (
            <Player audio_id={id} />
        );
    }

    render() {


        const { location } = this.props;
        const { history } = this.props;
        const { children } = this.props;

        return (
            <div>
                <Header />
                <Nav location={location} history={history}/>

                <div className="container">
                    <div className="row">
                        <div className="col-lg-12">
                            {this.props.children}
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-12">
                            <div className="song-player">
                                {this.state.isSongPlaying ? this.renderTrack(this.state.playingTrackId) : null}
                            </div>
                        </div>
                    </div>
                    <Footer/>
                </div>
            </div>

        );
    }
}

on {this.props.children} the component is loading my pages components Search, Queue, and About, but i would like add callback props to my Search and Queue components.

On my wrapper Layout component I want to achieve the following:

import React from "react";

import Footer from "../common/Footer.js";
import Nav from "../common/Nav.js";
import Header from "../common/Header.js";

export default class Layout extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isSongPlaying: false,
            playingTrackId: "",
            playingList: []
        }
    }

    handleClickTrack(track) {
        this.setState({
           isSongPlaying: !this.state.isSongPlaying
        });

    }

    renderTrack(i) {
        return (
            <Player audio_id={id} />
        );
    }

    render() {


        const { location } = this.props;
        const { history } = this.props;
        const { children } = this.props;

        return (
            <div>
                <Header />
                <Nav location={location} history={history}/>

                <div className="container">
                    <div className="row">
                        <div className="col-lg-12">
                            {RENDER SEARCH WITH onClick prop}
                            {RENDER QUEUE WITH onClick prop}
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-12">
                            <div className="song-player">
                                {this.state.isSongPlaying ? this.renderTrack(this.state.playingTrackId) : null}
                            </div>
                        </div>
                    </div>
                    <Footer/>
                </div>
            </div>
        );
    }
}
2

2 Answers

0
votes

I'm using render={() => <Component/>} in my React apps to give my Routes props. Don't know if it's the perfect way. There might be other ways. But it's working! :)

Here's an example of one of your Routes:

<Route exact path="/queue" render={() => <Queue prop={something}/>} />
0
votes

You can pass the props to child component using childContextTypes static object.Define below context in parent Layout component.

static childContextTypes={
      isSongPlaying: React.PropTypes.bool,
        playingTrackId:React.PropTypes.string,
        playingList: React.PropTypes.array

 }

Then populate the value using getChildContext() in Layout class

  getChildContext=()=>{
   return {
   isSongPlaying: false,
    playingTrackId:"Any Value to child component that you are going to pass",
    playingList: [] //Array with value

  }
  }

Now you can get the value in child component (About.jsx or Search.jsx) by defining context types like below

static contextTypes={
   isSongPlaying: React.PropTypes.bool,
    playingTrackId:React.PropTypes.string,
    playingList: React.PropTypes.array

}

Now you can access the property value in child component using the context like below

    let isPlaying= this.context.isSongPlaying  //or 
    let playingTrackId=this.context.playingTrackId