[英]Communicate two React children components with onClick functionality
好的,我将尽力解释我的项目是如何设置的,以便您可以适当地帮助我确定如何进行此配置。
我有一个parent component
,它是一个smart component
。 通过该组件,可以访问我商店中的所有数据。
class DashboardPage extends React.Component {
componentDidMount() {
this.props.getTips();
}
render() {
return (
<div>
<div className="row">
<div className="col-sm-7">
<ContentBox
title="The Scoop"
footerText="Submit a Story"
showSlider
content={<TipOfTheDay tips={this.props.tips} />}
/>
</div>
</div>
</div>
)
}
}
DashboardPage.propTypes = {
getTips: PropTypes.func
}
function mapStateToProps(state, ownProps) {
tips: state.tips
}
function mapDispatchToProps(dispatch) {
return {
getTips: () => { dispatch(tipActions.loadTips());} ## This hits tipActions and runs the `action creator`: loadTips(). Which returns all tips from api.
}
}
export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage);
如您所见,我在smart component
内部包括了两个dumb components
smart component
, <ContentBox/>
和<TipOfTheDay/>
。 在dashboardPage
上,大约有7个<ContentBox/>
组件,每个组件都继承一个特殊的页眉/页脚标题,并通过showSlider
布尔值告知是否显示页脚。 这是<ContentBox/>
样子:
import React, {PropTypes} from 'react';
import Footer from './ContentBoxFooter';
const ContentBox = ({title, footerText, showSlider, content}) => {
return (
<div style={styles.root} className="col-sm-12">
<div style={styles.header} className="row">
<h3 style={styles.header.title}>{title}</h3>
<span style={styles.header.arrow} />
</div>
{content}
<Footer footerText={footerText} showSlider={showSlider} />
</div>
);
};
ContentBox.propTypes = {
title: PropTypes.string,
footerText: PropTypes.string,
showSlider: PropTypes.bool,
content: PropTypes.object
};
export default ContentBox;
这是页脚:
import React, {PropTypes} from 'react';
import styles from './contentBoxStyles';
import Previous from './svg/Previous';
import Next from './svg/Next';
import Add from './svg/Add';
import consts from '../../styles/consts';
const ContentBoxFooter = ({footerText, showSlider}) => {
if (footerText != undefined) {
return (
<div style={styles.footer} className="row">
{
showSlider ?
<div>
<Previous fillColor={consts.orange} height="20px" width="20px"/>
<span style={styles.bar}>|</span>
<Next fillColor={consts.orange} width="20px" height="20px"/>
</div> : <div style={styles.emptyArrow} />
}
<div style={styles.footer.link}>
<span style={styles.footer.link.text}>{footerText}</span>
<Add fillColor={consts.orange} height="24px" width="24px" />
</div>
</div>
);
} else {
return(null);
}
};
ContentBoxFooter.propTypes = {
footerText: PropTypes.string,
showSlider: PropTypes.bool
};
export default ContentBoxFooter;
很少! 所以这是我需要添加onClick
功能的地方。 需要将此功能添加到作为SVG的<Previous/>
和<Next/>
组件中。 我试图做的是为插入的技巧创建一个滑块。显然,会有<Footer/>
组件需要相同的功能,但除了技巧之外,它们还控制其他数据。 因为我是React
& Redux
新手,所以我不确定如何执行此操作,而不仅仅是执行此操作,而是以“ Redux”的方式执行。
如何获得嵌套在其他dumb components
中的这两个svg
组件,它们是dumb components
,以对页面上的特定数据执行onClick功能? 我希望这是有道理的。 为了更加清楚,这是我在<TipOfTheDay/>
组件中所做的工作:
const tipOfTheDay = ({tips}) => {
return (
<div style={styles.tipBody} className="row">
{
tips.map(function(tip, key) {
return (
<div key={key} className="myTips">
<h3 style={styles.tipBody.header}>{tip.title}</h3>
<p style={styles.tipBody.content}>{tip.content}</p>
</div>
);
})
}
</div>
);
};
tipOfTheDay.propTypes = {
tips: PropTypes.array.isRequired
};
export default tipOfTheDay;
感谢您在阅读/回复/协助此问题时所花的任何时间。 我是一个相当新的开发人员,对我来说这也是新技术。
我不确定您如何实现下一个和上一个组件,但是由于您使用了React-Redux,因此您可以创建额外的容器来包装这些组件并将Redux Action传递给它们,例如:
// PreviousComponent.jsx
var Previous React.createClass({
propTypes: {
goToPrevious: React.PropTypes.func,
},
render: function() {
return (
<div onClick={this.props.goToPrevious}>
...
</div>
);
}
};
export default Previous;
//PreviousContainer.jsx
import ReactRedux from 'react-redux';
import Previous from './PreviousComponent';
var mapStateToProps = (state, props) => {
return {};
};
var mapDispatchToProps = (dispatch) => {
return {
goToPrevious: () => {
dispatch(Actions.goToPrevious());
},
}
};
var PreviousContainer = ReactRedux.connect(
mapStateToProps,
mapDispatchToProps
)(Previous);
export default PreviousContainer;
通过直接在组件周围添加容器包装器,您可以将redux操作连接到上一个图像/幻灯片/任何内容,直接进入您的React组件。 然后,当您想在ContentBoxFooter中使用该动作时,请导入PreviousContainer并将其放置在想要Previous组件的位置,例如:
//ContentBoxFooter.jsx
import PreviousContainer from './PreviousContainer'
const ContentBoxFooter = ({footerText, showSlider}) => {
if (footerText != undefined) {
return (
<div style={styles.footer} className="row">
{
showSlider ?
<div>
/*
* Add the PreviousContainer here where before you were only using your regular Previous component.
*/
<PreviousContainer fillColor={consts.orange} height="20px" width="20px"/>
<span style={styles.bar}>|</span>
<Next fillColor={consts.orange} width="20px" height="20px"/>
</div> : <div style={styles.emptyArrow} />
}
<div style={styles.footer.link}>
<span style={styles.footer.link.text}>{footerText}</span>
<Add fillColor={consts.orange} height="24px" width="24px" />
</div>
</div>
);
} else {
return(null);
}
};
ContentBoxFooter.propTypes = {
footerText: PropTypes.string,
showSlider: PropTypes.bool
};
通过将Next和Previous组件都包装在将动作传递给它们的容器中,您可以将Redux动作直接连接到组件中,而不必从应用程序的根组件传递它们。 另外,这样做还可以使您隔离调用某些动作的位置。 您的上一个按钮可能是唯一要调用上一个动作的组件,因此通过将其放在该组件周围的容器包装中,可以确保仅在需要的地方使用上一个动作。
编辑:
如果必须处理多个动作,最好在更高级别上定义它们。 在这种情况下,由于ContentBox是常见的突破点,因此我将为每种类型的内容框定义单独的Previous操作,并将它们传递到每个ContentBox实例中:
var DashboardApp = React.createClass({
propTypes: {
TipsPrevious: React.PropTypes.function,
NewsPrevious: React.PropTypes.function,
},
render: function() {
<div>
<ContentBox
previousAction={this.props.TipsPrevious}
contentType='Tips'
/>
<ContentBox
previousAction={this.props.NewsPrevious}
contentType='News'
/>
...
</div>
},
});
在子组件中向下传递操作,直到到达上一个组件,然后将该操作附加到上一个组件上的“ onClick”处理程序。
这背后的想法是,您希望将参数的范围限制为尽可能少的代码。 例如,如果您在页面上添加了一个显示用户信息的配置文件组件,则可能希望在该组件周围添加一个容器,并传入与用户相关的信息/操作,而不将该信息传递给应用程序的其余部分。 通过这样做,可以更轻松地将信息集中在需要的地方。 如果必须修复错误,它还可以帮助您弄清代码中发生了什么更改/操作。
在上面的示例中,如果仪表板组件是您的根组件,则只需将Redux操作传递到包装它的容器中。 但是,如果仪表板组件本身是嵌套组件,请通过自定义容器将操作传递到其中,以使这些操作不会传播到不需要查看它的代码中:
<AppRoot>
<PageHeader/>
<DashboardContainer />
<PageSidebar />
<PageFooter />
</AppRoot>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.