我正在使用Alex Bank's "Building a Polling App with Socket IO and React.js" (Lynda.com),但我正在尝试将其升级到react-router 1.0.0-RC1。
以下解决方案,只需跳过所有
请不要发给我文件,这对我不起作用,我想我必须太厚才能理解文档中的“简洁”。
我有一个主要的APP有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>
);
}
}
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>
);
}
}
虽然应用程序运行,并且我已阅读文档,但仍无法将APP的this.state.status作为属性传递给Audience应用程序。
我已经在这2天没有用,但它变得令人沮丧。 TGIF。
期望的结果:
当浏览器打开到localhost:3000时,默认页面 (Audience.js),读作:
Untitled Presentation - connected Audience - connected
我无法将连接状态传递给Audience组件,因此 “连接”字样未显示在“受众”旁边。我是连接的,正如Header的“Untitled Presentation - connected”
所证明的那样
有人可以在这里帮助我。
非常感谢!
答案 0 :(得分:1)
在APP
组件中,您需要包含以下内容:
{React.cloneElement(this.props.children, {status: this.state.status })}
然后在audience
组件中,您将this.props.status
提供该组件。
修改强>
我刚注意到你有一个循环依赖。我建议摆脱它,以便依赖只在一个方向:
routes.js --> app.js --> audience.js
看看这个example。这可以通过提取两个React类分解为三个文件:
main.js
这会呈现路线App.js
这会呈现应用并包含子路由Taco.js
这就是taco。然后可以表示如下:
main.js --> App.js --> Taco.js
答案 1 :(得分:0)
<强> SOLUTION: 强>
正如Clarkie所提到的,我确实有循环依赖性,因为我正在遵循使用react-router 0.13并将APP作为入口点的传统设置。
此问题的大部分帮助来自cluster pattern
悲伤&#39;无法找到详细的帮助 直接来自react-router文档。
我的新切入点现在是:
<强> 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')
);
<强> Routes.js:强>
注意:我特别喜欢他们的路线,因为我能看到相当 清楚地知道如何为大型应用转变这种动态(来自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>
);
}
}
<强> 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>
);
}
}
期望的结果: