我无法绕过这个问题。我正在写一个仪表板应用程序,以反应。我试图保持良好和模块化。我有两个布局类“row.js”& “col.js”他们基本上是返回bootstrap响应网格元素,“col-sm-3”等。
我创建了一个widget类和一个widget-expandable类。窗口小部件类返回带有一些样式的div,窗口小部件可扩展类扩展窗口小部件类,并添加一个单击处理程序以扩展到完整的浏览器宽度。然后我创建自定义窗口小部件类,以扩展这些窗口小部件类。这些自定义类将图形或表格等添加到实际组件中。我试图解决的问题是:
在我的dashboard.jsx中,我有:
<Row>
<Col size="sm" num="3">
<SpeakerFees expanded={false}/>
</Col>
<Col size="sm" num="9">
<ProgramStatusByZoneOverview />
</Col>
</Row>
我想点击窗口小部件组件,将其传递给最近的祖先,“”并警告同一行中的其他窗口小部件。根据反应提升状态文档,我们应该提升到最近的祖先。在这种情况下,两个元素向上。这很讨厌lol
因为仪表板的布局最多只包含10个小部件,所以我认为最好只是在dashboard.jsx中对它们进行硬编码,而不是使用某种循环。以下是我的其他课程。
dashboard.jsx
var React = require('react');
var ReactDOM = require('react-dom');
import { Row } from './layout/row.jsx';
import { Col } from './layout/col.jsx';
import { TotalWidget } from './widgets/total-widget.jsx';
import { ProgramsPlannedBySeries } from './widgets/programs-planned-by-series.jsx';
import { SpeakerFees } from './widgets/speaker-fees.jsx';
import { ProgramStatusByZoneOverview } from './widgets/program-status-by-zone-overview.jsx';
import 'bootstrap/dist/css/bootstrap.css';
import '../styles/app.scss';
class Dashboard extends React.Component {
render() {
var list = [
{
"size": "sm",
"num": "3"
},{
"size": "sm",
"num": "3"
},{
"size": "sm",
"num": "3"
},{
"size": "sm",
"num": "3"
}
]
return (
<div className="container">
<Row>
{list.map(function(object, i){
return (
<Col key={i.toString()} size={object.size} num={object.num}><TotalWidget key={i.toString()} /></Col>
);
})}
</Row>
<Row>
<Col size="sm" num="12">
<ProgramsPlannedBySeries />
</Col>
</Row>
<Row>
<Col size="sm" num="3">
<SpeakerFees expanded={false}/>
</Col>
<Col size="sm" num="9">
<ProgramStatusByZoneOverview />
</Col>
</Row>
<Row>
<Col size="sm" num="3">
<SpeakerFees expanded={false}/>
</Col>
<Col size="sm" num="9">
<ProgramStatusByZoneOverview />
</Col>
</Row>
<Row>
<Col size="sm" num="3">
<SpeakerFees expanded={false}/>
</Col>
<Col size="sm" num="9">
<ProgramStatusByZoneOverview />
</Col>
</Row>
</div>
);
}
}
ReactDOM.render(<Dashboard />, document.getElementById('widgets-wrapper'));
和我的小部件类:
widget.jsx
var React = require('react');
import {TweenMax, Power2, TimelineLite} from "gsap";
export class WidgetMenu extends React.Component {
constructor() {
super();
this.click = this.click.bind(this);
}
click() {
alert()
}
render() {
return (
<span onClick={this.click} className={"glyphicon glyphicon-option-horizontal elipsis " + this.props.state} ></span>
);
}
}
export class Widget extends React.Component {
constructor(props) {
super(props);
this.state = {'scale': false, 'class': ''};
this.hover = this.hover.bind(this);
}
hover() {
if(!this.state.scale){
this.setState({'scale': true, 'class': 'scaleUp'})
}else{
this.setState({'scale': false, 'class': ''})
}
}
click() {
// alsert('widget')
}
render() {
return (
<div onClick={this.click} onMouseEnter={this.hover} onMouseLeave={this.hover} className="widget"><WidgetMenu state={this.state.class} />{ this.props.children }</div>
)
}
}
和widget-expandable.jsx
widget-expandable.jsx
import { Widget, WidgetMenu } from './widget.jsx';
var React = require('react');
export class WidgetExpandable extends Widget {
constructor(props) {
super(props);
}
render() {
return (
<div onMouseEnter={this.hover} onMouseLeave={this.hover} className="widget"><WidgetMenu state={this.state.class} />{ this.props.children }</div>
)
}
}
以下两个自定义小部件将是dashboard.jsx中的cols / rows:
speaker-fee.jsx
"use strict";
var React = require('react');
var Highcharts = require('highcharts');
import { WidgetExpandable } from './widget-expandable.jsx';
export class SpeakerFees extends React.Component {
render() {
return (
<WidgetExpandable handleClick={this.props.handleClick}>
<div id="speaker-fees-chart"></div>
</WidgetExpandable>
);
}
}
和
program-status.jsx
"use strict";
var React = require('react');
import { Widget } from './widget.jsx';
export class ProgramStatusByZoneOverview extends React.Component {
render() {
return (
<Widget keyId={1}>
<table className="table" id="speaker-fees-table">
<thead>
<tr>
<th>Speaker Fees, Travel...</th>
<th>Budgeted Spend</th>
<th>Actual Spend</th>
<th>Variance</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fee For Service</td>
<td>250,000</td>
<td>150,000</td>
<td>-1.5%</td>
</tr>
<tr>
<td>Fee For Service</td>
<td>250,000</td>
<td>150,000</td>
<td>-1.5%</td>
</tr>
<tr>
<td>Fee For Service</td>
<td>250,000</td>
<td>150,000</td>
<td>-1.5%</td>
</tr>
<tr>
<td>Fee For Service</td>
<td>250,000</td>
<td>150,000</td>
<td>-1.5%</td>
</tr>
<tr>
<td>Fee For Service</td>
<td>250,000</td>
<td>150,000</td>
<td>-1.5%</td>
</tr>
</tbody>
</table>
</Widget>
);
}
}
答案 0 :(得分:0)
我想出来了。关键是从我的row.js类开始。我在row.js类上创建了一个click事件,它在行类上设置了expanded = false状态。然后循环遍历每个子项并将此单击处理程序添加为prop。然后将这个道具添加为孩子们的onclick。
export class Widget extends React.Component {
constructor(props) {
super(props);
this.state = {'scale': false, 'class': ''};
this.hover = this.hover.bind(this);
}
hover() {
if(!this.state.scale){
this.setState({'scale': true, 'class': 'scaleUp'})
}else{
this.setState({'scale': false, 'class': ''})
}
}
render() {
console.log(this.props.onExpandChange)
return (
<div onClick={this.props.onExpandChange} onMouseEnter={this.hover} onMouseLeave={this.hover} className="widget"><WidgetMenu state={this.state.class} />{ this.props.children }</div>
)
}
}
"use strict";
var React = require('react');
export class Col extends React.Component {
render() {
const childrenWithProps = React.Children.map(this.props.children,
(child) => React.cloneElement(child, {
onExpandChange: this.props.onExpandChange
})
);
return (
<div className={"col-" + this.props.size + '-' + this.props.num}>
{childrenWithProps}
</div>
);
}
}
"use strict";
var React = require('react');
export class Row extends React.Component {
constructor(props) {
super(props);
this.state = {expanded: false}
this.click = this.click.bind(this);
}
click() {
this.setState({"expanded": !this.state.expanded});
console.log(this.state.expanded);
}
render() {
const childrenWithProps = React.Children.map(this.props.children,
(child) => React.cloneElement(child, {
onExpandChange: this.click
})
);
return (
<div className="row">{ childrenWithProps }</div>
)
}
}