0

我正在研究Alex Bank 的“使用 Socket IO 和 React.js 构建轮询应用程序”(Lynda.com),但我正在尝试将其升级到 react-router 1.0.0-RC1。

下面的解决方案,跳过所有这些

请不要将我发送到文档,它对我不起作用,我想我一定太厚了,无法理解文档的“精髓”。

我有一个带有 3 条子路线(观众、演讲者和董事会)的主应用程序。

到目前为止我的代码:

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>
    );
  }
}

路由.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>
   );
 }

}

尽管应用程序运行,并且我已阅读文档,但我仍然无法将 APP 的 this.state.status 作为属性传递给 Audience 应用程序。

我已经在这 2 天无济于事,这变得令人沮丧。动图。

期望的结果:

当浏览器打开到 localhost:3000 时,默认页面 (Audience.js) 应如下所示:

 Untitled Presentation - connected

 Audience - connected

我无法将已连接状态传递给受众组件,因此“已连接”一词未显示在受众旁边。Header 的“Untitled Presentation - connected”证明了我已连接

有人可以在这里帮助我。

非常感谢!

4

2 回答 2

1

在您的APP组件中,您需要包含以下内容:

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

然后在您的audience组件中,您可以将其作为this.props.status.

编辑:

我刚刚注意到你有一个循环依赖。我建议摆脱它,以便依赖只在一个方向:

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

看看这个例子。通过提取两个 React 类,可以将其分解为三个文件:

  1. main.js这会呈现路线
  2. App.js这会呈现应用程序并包含子路由
  3. Taco.js这使得炸玉米饼。

这可以表示如下:

    main.js --> App.js --> Taco.js
于 2015-10-02T13:18:03.553 回答
0

解决方案:

正如 Clarkie 提到的,我确实有循环依赖,因为我遵循的是使用 react-router 0.13 并以 APP 作为入口点的旧设置。

这个问题的大部分帮助来自iam4x/isomorphic-flux-boilerplate

无法 直接从 react-router 文档中找到“可悲”的详细帮助。


我的新切入点现在是:

索引.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:

注意:我特别喜欢他们如何进行路由,因为我可以非常 清楚地看到如何为大型应用程序转换这种动态(w/数据来自 Db)。

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>
     );
   }
 }

显示.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>
        );
    }
}

期望的结果:

在此处输入图像描述

于 2015-10-02T17:53:25.247 回答