gma*_*man 5 javascript reactjs
有可能让React移动一个元素而不是在它改变它在DOM中的位置时重新创建它吗?
让我们假设我正在创建一个2窗格组件,我希望能够隐藏/取消隐藏一个窗格.我们也可以想象窗格本身很重.在我的例子中,每个窗格都有超过2000个元素.
在我的实际代码中,当有2个窗格时,我正在使用分割器.为了只显示一个窗格,我需要删除拆分器并用div替换它.
下面的代码模拟了这一点.如果有一个窗格,则使用a div来包含窗格.如果有2个窗格pre用于包含它们.在我的情况下,它将是div1痛苦和splitter2.
因此,document.createElement我发现不仅创建了容器,而且还重新创建了内部元素.换句话说,在我的代码中,当从splitter-> div开始时,2000+元素窗格将完全重新创建,这很慢.
有没有办法有效地告诉React."嘿,不要重新创建这个组件,只是移动它?"
class TwoPanes extends React.Component {
constructor(props) {
super(props);
}
render() {
const panes = this.renderPanes();
if (panes.length === 2) {
return React.createElement('pre', {className: "panes"}, panes);
} else {
return React.createElement('div', {className: "panes"}, panes);
}
}
renderPanes() {
return this.props.panes.map(pane => {
return React.createElement('div', {className: "pane"}, pane);
});
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
panes: [
"pane one",
"pane two",
],
};
}
render() {
const panes = React.createElement(TwoPanes, {panes: this.state.panes}, null);
const button = React.createElement('button', {
onClick: () => {
const panes = this.state.panes.slice();
if (panes.length === 1) {
panes.splice(0, 0, "pane one"); // insert pane 1
} else {
panes.splice(0, 1); // remove pane 1
}
this.setState({panes: panes});
},
}, "toggle pane one");
return React.createElement('div', {className: "outer"}, [panes, button]);
}
}
// wrap document.createElement so we can see if new elements are created
// vs reused
document.createElement = (function(oldFn) {
let count = 0;
let inside = false;
return function(type, ...args) {
if (!inside) { // needed because SO's console wrapper calls createElement
inside = true;
console.log(++count, "created:", type);
inside = false;
}
return oldFn.call(this, type, ...args);
}
}(document.createElement));
ReactDOM.render(
React.createElement(App, {}, null),
document.getElementById('root')
);Run Code Online (Sandbox Code Playgroud)
html { box-sizing: border-box; }
*, *:before, *:after { box-sizing: inherit; }
body { margin: 0; }
#root { width: 100vw; height: 100vh; }
.outer {
width: 100%;
height: 100%;
}
.panes {
width: 100%;
height: 100%;
display: flex;
flow-direction: row;
justify-content: space-between;
}
.pane {
flex: 1 1 auto;
border: 1px solid black;
}
button {
position: absolute;
left: 10px;
top: 30px;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
我不认为有一种方法可以在DOM树木周围移动,即使有 - 它会非常昂贵,如同
O(n) 不同类型的两个元素将产生不同的树木
DOM,您首先需要将其从树中分离,这意味着它仍然需要在以后重新应用,这是一个瓶颈.插入HTML到DOM非常昂贵,即使缓存/分段.我的建议是使用CSS,因为display: none/ display: block比重新应用缓存要快得多DOM.
class TwoPanes extends React.Component {
render() {
return (
<div>
<Pane1 />
<Pane2 style={this.state.panes.length === 2 ? {} : {display: 'none'} } />
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4621 次 |
| 最近记录: |