javascript - 仅访问父级来反应兄弟级通信
问题描述
我正在尝试创建类似于React Bootstrap 的下拉组件的东西。我的起始骨架如下所示:
import React from 'react';
const DropDown = props => {
return <div className="dropdown-container">{props.children}</div>;
};
const DropDownToggle = props => {
return <div className="dropdown-toggle">{props.children}</div>;
};
const DropDownContent = props => {
return <div className="dropdown-content">{props.children}</div>;
};
export { DropDown, DropDownToggle, DropDownContent };
这些组件将像这样使用:
<DropDown>
<DropDownToggle>
{/*
The content inside here should be customizable so the user of
these components can specify whatever they want for the toggle
*/}
<button type="button">
my button
</button>
</DropDownToggle>
<DropDownContent>
{/*
The content inside here should be customizable so the user of
these components can specify whatever they want for the content of
the dropdown
*/}
<ContentComponent/>
</DropDownContent>
</DropDown>
有没有办法可以在两个子组件(DropDownContent 和 DropDownToggle)之间进行通信?我可以访问父组件,到目前为止它只接收并显示子组件,但我想以某种方式在子组件之间进行通信,以便用户可以单击切换来打开/关闭内容。我不想使用 redux。
先感谢您!
编辑
我最终采用了@Train 在下面他/她的评论中建议的方法。我最初希望能够手动嵌套组件,但对我来说最重要的是让状态在父组件中是自包含的。能够定义切换按钮的 HTML 以及内容的 HTML 也是一项要求。我的最终实现允许这两种情况,看起来像这样:
import React from 'react';
import PropTypes from 'prop-types';
export class Dropdown extends React.Component {
state = {
isOpen: false,
};
onDropDownToggleClick = () => {
this.setState({ isOpen: !this.state.isOpen });
};
render() {
let contentClasses = 'dropdown-content';
if (this.state.isOpen) {
contentClasses += ' show';
}
return (
<div className="dropdown-container">
<div className="dropdown-toggle" onClick={this.onDropDownToggleClick}>
{this.props.toggle}
</div>
<div className={contentClasses}>{this.props.content}</div>
</div>
);
}
}
Dropdown.propTypes = {
toggle: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
content: PropTypes.oneOfType([PropTypes.string, PropTypes.element])
.isRequired,
};
export default Dropdown;
使用它:
const dropDownToggle = (
<button type="button">
Dropdown
</button>
);
const dropDownContent = 'content';
<DropDown
toggle={dropDownToggle}
content={dropDownContent}
/>
解决方案
对于诸如切换内容之类的东西,您可以使用composition
而不是inheritance
传递数据。
这是通过props.children
财产完成的。
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
{props.children}
</FancyBorder>
);
}
class SignUpDialog extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSignUp = this.handleSignUp.bind(this);
this.state = {login: ''};
}
render() {
return (
<Dialog title="Mars Exploration Program"
message="How should we refer to you?">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
Sign Me Up!
</button>
</Dialog>
);
}
handleChange(e) {
this.setState({login: e.target.value});
}
handleSignUp() {
alert(`Welcome aboard, ${this.state.login}!`);
}
}
在render()
我正在渲染Dialog
组件并传递道具。props.children
和自定义 propstitle, message
这让我们可以将子元素直接传递到输出中,我们甚至可以添加来自其他类的组件,就像我对SignUpDialog
.
推荐阅读
- r - 如何将 output$suffix 名称的后缀合并到 R shiny 中的 input$suffix_rows_selected 函数中?
- r - 将反应输出存储在向量中 - Shiny R
- azure - Azure 应用服务未记录所有 App Insights 依赖项
- amazon-web-services - 为 CodeDeploy 使用最新的 ECS 任务修订
- linux - 无法在并行脚本中使用位置参数
- c# - 无法确定 JSON 对象类型系统参数异常
- c# - 如何使用 c# 将 TapGestureRecognizer 添加到从 JSON 创建的项目中?
- ruby-on-rails - Ruby on Rails 应用程序中的 sitemap.xml 问题
- reactjs - 如何将上下文与重定向联系起来
- typescript - 打字稿函数重载“没有重载匹配此调用”