Reactjs 是否可以通过从其道具之一调用函数来获取嵌套的内部React组件的名称?
我有这个部分:Reactjs 是否可以通过从其道具之一调用函数来获取嵌套的内部React组件的名称?,reactjs,material-ui,Reactjs,Material Ui,我有这个部分: class DashboardPage extends Component { constructor(props) { super(props); this.state = { loading: true, shownPage: ActiveDeals, error: false, errorDetails: null, activeIcon: "Home" }; } compo
class DashboardPage extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
shownPage: ActiveDeals,
error: false,
errorDetails: null,
activeIcon: "Home"
};
}
componentDidMount() {
//
}
setShownPage = (name, iconName) => () => {
this.setState({ shownPage: name, activeIcon: iconName });
};
getIconColor = () => {
// could I call this from the Home component and check its name? Or know the caller?
return "primary";
};
render() {
const { classes } = this.props;
const menuItems = (
<List>
<ListItem className={classNames(classes.listItem)} button onClick={this.setShownPage(ActiveDeals, "Home")}>
<ListItemIcon className={classNames(classes.listItemIcon)}>
<Home color={this.state.activeIcon === "Home" ? "primary" : "secondary"} />
</ListItemIcon>
</ListItem>
<ListItem className={classNames(classes.listItem)} button onClick={this.setShownPage(UpcomingDates, "CalendarToday")}>
<ListItemIcon className={classNames(classes.listItemIcon)}>
<CalendarToday color={this.state.activeIcon === "CalendarToday" ? "primary" : "secondary"} />
</ListItemIcon>
</ListItem>
<ListItem className={classNames(classes.listItem)} button onClick={this.setShownPage(DealsPipeline, "FilterList")}>
<ListItemIcon className={classNames(classes.listItemIcon)}>
<FilterList color={this.state.activeIcon === "FilterList" ? "primary" : "secondary"} />
</ListItemIcon>
</ListItem>
</List>
);
return (
<MainFrame
route={this.props.match.url}
title={this.state.shownPage.title}
menuItems={menuItems}
open={this.state.open}
topRightFeature={this.state.shownPage.topRightFeature}
>
<this.state.shownPage />
<div>Primary color is {this.props.theme.palette.primary.main}</div>
</MainFrame>
);
}
}
export default withStyles(styles, { withTheme: true })(DashboardPage);
类仪表板页扩展组件{
建造师(道具){
超级(道具);
此.state={
加载:对,
shownPage:ActiveDeals,
错误:false,
errorDetails:null,
活动图标:“主页”
};
}
componentDidMount(){
//
}
setShownPage=(名称,图标名)=>()=>{
this.setState({shownPage:name,activeIcon:iconName});
};
getIconColor=()=>{
//我可以从Home组件调用它并检查它的名称吗?或者知道调用方吗?
返回“主”;
};
render(){
const{classes}=this.props;
常量菜单项=(
);
返回(
主色是{this.props.theme.palete.Primary.main}
);
}
}
使用样式导出默认值(样式,{withTheme:true})(仪表板页面);
。。。我习惯于在后端语言中使用nameof()
和type()
来了解给定实例的名称。在React中,我还没有找到一种方法来做到这一点
我不希望基于状态设置图标颜色(使用硬编码字符串,糟糕),而是希望有一种功能性的方法来遍历dom树以查找相关子级,或者只知道调用getIconColor
方法的图标名称,以便将其与活动状态进行比较
组件在使用“知道”从中调用的函数(例如,
Home
)时,是否有任何方法可以设置属性?如果在使用该函数的组件中绑定该函数,则可以获取调用方的标识。这只能在类组件中工作
大概是这样的:
import React, { Component } from "react";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import { withStyles } from "@material-ui/core/styles";
import Home from "@material-ui/icons/Home";
import CalendarToday from "@material-ui/icons/CalendarToday";
import FilterList from "@material-ui/icons/FilterList";
const styles = {};
const ActiveDeals = () => {
return <div>ActiveDeals Page!</div>;
};
const UpcomingDates = () => {
return <div>UpcomingDates Page!</div>;
};
const DealsPipeline = () => {
return <div>DealsPipeline Page!</div>;
};
const listItemStyles = {
listItem: {
/* whatever styles you need */
},
listItemIcon: {
/* whatever styles you need */
}
};
const DashboardListItem = withStyles(listItemStyles)(
({ Page, Icon, ShownPage, classes, setShownPage }) => {
return (
<ListItem
className={classes.listItem}
button
onClick={() => setShownPage(Page)}
>
<ListItemIcon className={classes.listItemIcon}>
<Icon color={ShownPage === Page ? "primary" : "secondary"} />
</ListItemIcon>
</ListItem>
);
}
);
const menuItems = [
{ Page: ActiveDeals, Icon: Home },
{ Page: UpcomingDates, Icon: CalendarToday },
{ Page: DealsPipeline, Icon: FilterList }
];
class DashboardPage extends Component {
constructor(props) {
super(props);
this.state = {
shownPage: ActiveDeals
};
}
setShownPage = page => {
this.setState({ shownPage: page });
};
render() {
const mappedMenuItems = menuItems.map((menuItem, index) => (
<DashboardListItem
key={index}
{...menuItem}
ShownPage={this.state.shownPage}
setShownPage={this.setShownPage}
/>
));
return (
<div>
<List>{mappedMenuItems}</List>
<this.state.shownPage />
<div>Primary color is {this.props.theme.palette.primary.main}</div>
</div>
);
}
}
export default withStyles(styles, { withTheme: true })(DashboardPage);
类Apple扩展React.Component{
建造师(道具){
超级(道具);
this.getName=props.getName.bind(this);
}
render(){
return我是一个{this.getName()};
}
}
类。组件{
getName(){
返回this.constructor.name;
}
render(){
返回(
);
}
}我认为您试图以一种忽略React的声明能力和组件组合提供的可能性的方式来解决这个问题。列表项之间的代码重复要求引入另一个组件:
const listItemStyles = {
listItem: {
/* whatever styles you need */
},
listItemIcon: {
/* whatever styles you need */
}
};
const DashboardListItem = withStyles(listItemStyles)(
({ Page, Icon, ShownPage, classes, setShownPage }) => {
return (
<ListItem
className={classes.listItem}
button
onClick={() => setShownPage(Page)}
>
<ListItemIcon className={classes.listItemIcon}>
<Icon color={ShownPage === Page ? "primary" : "secondary"} />
</ListItemIcon>
</ListItem>
);
}
);
完整代码如下所示:
import React, { Component } from "react";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import { withStyles } from "@material-ui/core/styles";
import Home from "@material-ui/icons/Home";
import CalendarToday from "@material-ui/icons/CalendarToday";
import FilterList from "@material-ui/icons/FilterList";
const styles = {};
const ActiveDeals = () => {
return <div>ActiveDeals Page!</div>;
};
const UpcomingDates = () => {
return <div>UpcomingDates Page!</div>;
};
const DealsPipeline = () => {
return <div>DealsPipeline Page!</div>;
};
const listItemStyles = {
listItem: {
/* whatever styles you need */
},
listItemIcon: {
/* whatever styles you need */
}
};
const DashboardListItem = withStyles(listItemStyles)(
({ Page, Icon, ShownPage, classes, setShownPage }) => {
return (
<ListItem
className={classes.listItem}
button
onClick={() => setShownPage(Page)}
>
<ListItemIcon className={classes.listItemIcon}>
<Icon color={ShownPage === Page ? "primary" : "secondary"} />
</ListItemIcon>
</ListItem>
);
}
);
const menuItems = [
{ Page: ActiveDeals, Icon: Home },
{ Page: UpcomingDates, Icon: CalendarToday },
{ Page: DealsPipeline, Icon: FilterList }
];
class DashboardPage extends Component {
constructor(props) {
super(props);
this.state = {
shownPage: ActiveDeals
};
}
setShownPage = page => {
this.setState({ shownPage: page });
};
render() {
const mappedMenuItems = menuItems.map((menuItem, index) => (
<DashboardListItem
key={index}
{...menuItem}
ShownPage={this.state.shownPage}
setShownPage={this.setShownPage}
/>
));
return (
<div>
<List>{mappedMenuItems}</List>
<this.state.shownPage />
<div>Primary color is {this.props.theme.palette.primary.main}</div>
</div>
);
}
}
export default withStyles(styles, { withTheme: true })(DashboardPage);
import React,{Component}来自“React”;
从“@material ui/core/List”导入列表;
从“@material ui/core/ListItem”导入ListItem;
从“@material ui/core/ListItemIcon”导入ListItemIcon;
从“@material ui/core/styles”导入{withStyles}”;
从“@material ui/icons/Home”导入主页;
从“@material ui/icons/CalendarToday”导入CalendarToday;
从“@material ui/icons/FilterList”导入过滤器列表;
常量样式={};
const ActiveDeals=()=>{
返回ActiveDeals页面!;
};
常数更新日期=()=>{
返回更新日期页面!;
};
const dealsipeline=()=>{
返回交易列表页面!;
};
常量listItemStyles={
列表项:{
/*你需要什么款式都行*/
},
listItemIcon:{
/*你需要什么款式都行*/
}
};
const DashboardListItem=带有样式(listItemStyles)(
({Page,Icon,ShownPage,classes,setShownPage})=>{
返回(
设置显示页面(第页)}
>
);
}
);
常量菜单项=[
{Page:ActiveDeals,Icon:Home},
{页面:更新日期,图标:CalendarToday},
{Page:dealsipeline,Icon:FilterList}
];
类DashboardPage扩展组件{
建造师(道具){
超级(道具);
此.state={
shownPage:ActiveDeals
};
}
setShownPage=页面=>{
this.setState({shownPage:page});
};
render(){
const mappedMenuItems=menuItems.map((menuItem,index)=>(
));
返回(
{mappedMenuItems}
主色是{this.props.theme.palete.Primary.main}
);
}
}
使用样式导出默认值(样式,{withTheme:true})(仪表板页面);
下面是一个工作示例:
谢谢,我不知道
这个.constructor.name
。但是,只有在我自己定义组件的情况下才能使用它吗?当我在Material UI组件上尝试它时,我只得到了函数
。感谢您的回答。我不得不在地图
结果中添加一个键
,并从onClick中删除()=>
,但效果很好。我已经更新了答案,添加了这个键——好的捕获。在我的代码中,我已经删除了setShownPage
定义中的额外curry,因此()=>
在onClick
中是必需的。