我们想要改变孩子的父母内容。除了克隆每个孩子之外还有其他任何可能性将更改方法添加到道具中吗? 例如,可能会有更多的孩子,我们会遇到性能问题。我们也可以使用react-redux。但是,由于将整个组件保存到商店中是一种反模式,只有这种解决方案吗?
以下是使用React.cloneElement
。
父
export default class Parent extends PureComponent {
static propTypes = {
children: PropTypes.any
};
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
const content = React.Children.map(this.props.children, child =>
React.cloneElement(child, {
restoreContent: this.restoreContent.bind(this),
setContent: this.setContent.bind(this)
}));
this.setState({
...this.state,
content
});
}
componentWillReceiveProps(nextProps) {
const content = React.Children.map(nextProps.children, child =>
React.cloneElement(child, {
restoreContent: this.restoreContent.bind(this),
setContent: this.setContent.bind(this)
}));
this.setState({
...this.state,
content
});
}
setContent(content) {
this.setState({
...this.state,
content,
storedContent: this.state.content
});
}
restoreContent() {
this.setState({
...this.state,
content: this.state.storedContent,
storedContent: null
});
}
render() {
return <div>{this.state.content}</div>;
}
}
子
export default class Child extends PureComponent {
static propTypes = {
children: PropTypes.any,
restoreContent: PropTypes.func,
setContent: PropTypes.func
};
render() {
const content = (
<div>
<div>Changed-Content</div>
<button onClick={ () => this.props.restoreContent() }></button>
</div>
);
return (
<div>Default-Child-Content</div>
<button onClick={() => this.props.setContent(content)}>Change</button>
);
}
}
主要
<Parent>
<Child />
</Parent>
UseCase示例: 您想要使用肉丸菜单模拟移动屏幕。单击肉丸菜单,在移动屏幕内显示全屏选项列表。
.background {
background: green;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.mobileScreen {
width: 40%;
height: 80%;
background: blue;
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div class="background">
<div class="mobileScreen">
<div>Default-content</div>
<button>Change Content</button>
</div>
</div>
</body>
</html>