我有以下React应用程序:
class Item extends React.PureComponent {
state = {
id: Math.random()
};
divRef = React.createRef();
render() {
return <div ref={this.divRef}>
My id is {this.state.id}
</div>;
}
componentDidMount() {
// This is a DOM manipulation which React doesn't control. I use it to see whether React reuses the DOM element.
const colors = ['red', 'blue', 'green', 'navy', 'brown', 'violet'];
const color = colors[Math.floor(Math.random() * colors.length)];
this.divRef.current.style.color = color;
}
}
class App extends React.Component {
state = {
itemPosition: 'top'
};
render() {
return <React.Fragment >
<button onClick={() => this.setState({itemPosition: 'top'})}>Move to top</button>
<button onClick={() => this.setState({itemPosition: 'bottom'})}>Move to bottom</button>
<div className="container">
{this.state.itemPosition === 'top' ? <Item key="1"/> : null}
</div>
<div className="container">
{this.state.itemPosition === 'bottom' ? <Item key="1"/> : null}
</div>
</React.Fragment>;
}
}
ReactDOM.render(<App/>, document.querySelector('#app'));
.container {
border: solid 1px;
padding: 10px;
margin: 10px;
}
<script src="https://cdn.jsdelivr.net/npm/react@16.4.1/umd/react.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@16.4.1/umd/react-dom.development.js"></script>
<div id="app"></div>
在此示例中,App
组件在两个Item
中的一个渲染一个div
组件。每次安装Item
组件时都会出现随机外观,以检测是否重新安装。
如您所见,Item
元素每次移动到另一个父元素div
时都会重新安装。有没有一种方法可以将元素移动到另一个父元素而不进行卸载和安装,以保持元素状态和相应的DOM树?
P.S。我知道我可以通过将Item
状态移动到其道具来解决该示例,但这并非总是可能的,例如当DOM树由另一个非反应库控制时。