2015-10-02 1 views
0

Я работаю Alex Bank's "Building a Polling App with Socket IO and React.js" (Lynda.com), но я пытаюсь обновить его до взаимодействия с маршрутизатором 1.0.0-RC1.React-Router 1.0.0RC1 - Передача состояния как дочерних маршрутов

Solution below, just skip all this

Пожалуйста, не присылайте мне в документации, она не работает для меня, я предполагаю, что я должен быть слишком толстым, чтобы понять в документации по по «содержательность».

У меня есть основной APP с тремя дочерними маршрутами, (Аудитория, Спикер & Board).

Мой код до сих пор:

APP.js

import React, { Component } from 'react'; 
import io from 'socket.io-client'; 
import Header from './parts/Header'; 
import Routes from '../router/routes'; 
import { createHistory, useBasename } from 'history'; 

const history = useBasename(createHistory)({ 
    basename: '/' 
}); 

export default class APP extends Component { 

    constructor() { 
    super(); 
    this.state = ({ 
     status: 'disconnected', 
     title: '' 
    }); 
    } 

    componentWillMount() { 
    this.socket = io('http://localhost:3000'); 
    this.socket.on('connect', this.connect.bind(this)); 
    this.socket.on('disconnect', this.disconnect.bind(this)); 
    this.socket.on('welcome', this.welcome.bind(this)); 
    } 

connect() { 
    this.setState({status: 'connected'}); 
} 

disconnect() { 
    this.setState({status: 'disconnected'}); 
} 

welcome(serverState) { 
    this.setState({title: serverState.title}); 
} 

render() { 
    return (
    <div> 
     <Header title={ this.state.title } status={ this.state.status }/> 
     { /* I WANT TO PASS THIS.STATE.STATUS TO CHILD ROUTES */} 
     <Routes history={ history } /> 
    </div> 
    ); 
    } 
} 

Routes.js

import React, { Component } from 'react'; 
import Route from 'react-router'; 
import APP from '../components/APP'; 
import Audience from '../components/Audience'; 
import Board from '../components/Board'; 
import Speaker from '../components/Speaker'; 
import NotFound from '../components/NotFound'; 


export default class Routes extends Component { 
    constructor() { 
    super(); 
    } 

    render() { 
    return (
     <Route history={ this.props.history } component={ APP }> 
     <Route path="/" component={ Audience } /> 
     <Route path="audience" component={ Audience } /> 
     <Route path="board" component={ Board } /> 
     <Route path="speaker" component={ Speaker } /> 
     <Route path="*" component={ NotFound } /> 
     </Route> 
    ); 
    } 
} 

Audience.js

import React, { Component } from 'react'; 

export default class Audience extends Component { 

constructor() { 
    super(); 
} 


render() { 
    return (
    <div> 
     Audience - STUCK HERE!! - How to pass APP's this.state.status as a prop????   
    </div> 
    ); 
} 

}

Хотя прогонов приложения, и я прочитал документацию, я до сих пор не в состоянии передать this.state.status приложения как свойство к аудитории приложение.

Я был на этом в течение 2 дней безрезультатно, и это расстраивает. TGIF.

Desired Result:

When a browser is opened to localhost:3000, the default page (Audience.js), should read as:

Untitled Presentation - connected 

Audience - connected 

I cannot get the status of connected passed to the Audience component so the word 'connected' is not showing up next to Audience. I am connected as evidenced by Header's "Untitled Presentation - connected"

Может кто-нибудь помочь мне здесь.

Большое спасибо!

ответ

0

SOLUTION:

Как упоминалось Clarkie, я есть циклический Зависимость от, потому что я после установки унаследованного, который использовал реакцию-маршрутизатор 0,13 и имел APP, как точка входа.

Большая часть помощи для этой проблемы пришло из iam4x/isomorphic-flux-boilerplate

It is 'sad' detailed assistance could not have been found directly from the react-router documentation.


Моя новая точка входа в настоящее время:

index.js

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import Router from 'react-router'; 
import createBrowserHistory from 'history/lib/createBrowserHistory'; 

    const routerProps = { 
    routes: require('./router/routes'), 
    history: createBrowserHistory(), 
    createElement: (component, props) => { 
     return React.createElement(component, { ...props}); 
    } 
    }; 

    ReactDOM.render(
    React.createElement(Router, { ...routerProps }), 
    document.getElementById('root') 
); 

Маршруты. js:

Note: I especially like how they did the routes, because I can see quite clearly how to turn this dynamic (w/ data from Db) for large apps.

import React from 'react'; 
import { Route } from 'react-router'; 
import { generateRoute } from '../utils/localized-routes'; 

export default (
    <Route component={ require('../components/APP') }> 
    { generateRoute({ 
     paths: ['/', '/audience'], 
     component: require('../components/Audience') 
    }) } 
    { generateRoute({ 
     paths: ['/speaker'], 
     component: require('../components/Speaker') 
    }) } 
    { generateRoute({ 
     paths: ['board'], 
     component: require('../components/Board') 
    }) } 
    <Route path="*" component={ require('../components/NotFound') } /> 
    </Route> 
); 

локализованы-routes.js:

import React from 'react'; 
import { Route } from 'react-router'; 

export function generateRoute({ paths, component }) { 
    return paths.map(function(path) { 
    const props = { key: path, path, component }; 
    // Static `onEnter` is defined on 
    // component, we should pass it to route props 
    if (component.onEnter) props.onEnter = component.onEnter; 
    return <Route {...props} />; 
    }); 
} 

// SWEET!!! Nice touch. 
export function replaceParams(route, params) { 
    let parsedRoute = route.trim(); 
    Object.keys(params).forEach(function(paramKey) { 
    const param = ':' + paramKey; 
    const paramValue = params[paramKey]; 
    if (parsedRoute && parsedRoute.match(param)) { 
     parsedRoute = parsedRoute.replace(param, paramValue); 
    } 
    }); 
    return parsedRoute; 
} 

APP.js:

import React, { Component, PropTypes } from 'react'; 
import io from 'socket.io-client'; 
import Header from './parts/Header'; 

export default class APP extends Component { 
    static propTypes = { 
    children: PropTypes.element 
    } 

    constructor(props, context) { 
    super(props, context); 
    this.state = ({ 
    status: 'disconnected', 
    title: '' 
    }); 
} 

componentWillMount() { 
    this.socket = io('http://localhost:3000'); 
    this.socket.on('connect', this.connect.bind(this)); 
    this.socket.on('disconnect', this.disconnect.bind(this)); 
    this.socket.on('welcome', this.welcome.bind(this)); 
} 

connect() { 
    this.setState({ status: 'connected' }); 
} 

disconnect() { 
    this.setState({ status: 'disconnected' }); 
} 

welcome(serverState) { 
    this.setState({ title: serverState.title }); 
} 

renderChild =() => 
    React.cloneElement(this.props.children, { status: this.state.status }); 

render() { 
    return (
     <div> 
     <Header title={ this.state.title } status={ this.state.status }/> 
     { React.Children.map(this.props.children, this.renderChild) } 
     </div> 
    ); 
    } 
} 

Audience.js:

import React, { Component } from 'react'; 
import Display from './Display'; 

export default class Audience extends Component { 
    constructor(props) { 
    super(props); 
    } 

    render() { 
    return (
     <div> 
     Audience - { this.props.status } 
     <Display if={ this.props.status === 'connected' }> 
      <h1>Join the session</h1> 
     </Display> 
     </div> 
    ); 
    } 
} 

Display.js:

import React, { Component } from 'react'; 

export default class Display extends Component { 
    render() { 
    return (
     <div> 
     { this.props.if ? <div> { this.props.children } </div> : null } 
     </div> 
     ); 
    } 
} 

DESIRED RESULT:

enter image description here

+0

Пробовал ли вы спрашивать на странице github с реактивным маршрутизатором с вашей проблемой? Сопровождающий очень хорош, и он ответил в течение получаса, когда у меня возникла проблема. –

+0

Да, их ответ был кратким и неоднозначным, как будто я живу весь день и ночь, думая о реакции-маршрутизаторе. Не очень доволен своей «поддержкой». –

+0

Если вы что-то не понимаете, не нужно много просить их разъяснять. У меня не было ничего, кроме хорошего опыта работы с маршрутизатором. Вы также должны помнить, что владелец реактивного маршрутизатора поддерживает это, так как, ну, свободно и владеет репо, поэтому он собирается говорить, как будто вы знакомы с ним. –

1

В вашем APP компонента необходимо включить следующее:

{React.cloneElement(this.props.children, {status: this.state.status })} 

Затем в audience компоненты вы будете иметь, что доступны как this.props.status.

Edit:

Я только заметил, что у вас есть циклическую зависимость. Я рекомендовал бы избавиться от этого, так что зависимость только в одном направлении:

routes.js --> app.js --> audience.js 

Посмотрите на эту example.Это может быть разбито на три файла путем извлечения двух Реагировать классов:

  1. main.js это делает маршруты
  2. App.js это делает приложение и включает в себя дочерние маршруты
  3. Taco.js это делает тако~d.

Это может быть представлено следующим образом:

main.js --> App.js --> Taco.js 
+0

TypeError: Не удается прочитать свойство 'реквизита' неопределенной –

+0

Я только отредактированные мой ответ на ссылку на пример. Вам нужно исправить свою циклическую зависимость. – Clarkie

Смежные вопросы