2017-08-16 21 views
0

组件呈现以下React元素树。父DOM节点更改类型时ReactJS协调

<div> 
    <Counter /> 
</div> 

然后发生状态或道具变化并且触发渲染,导致以下React元素树。

<span> 
    <Counter /> 
</span> 

请问Counter组件的实例被完全重新实例化,构造函数和所有?

如果是这样,这是否相同的行为适用于非根节点如:

<div> 
    <div> 
    <Counter /> 
    </div> 
</div> 

过渡到...

<div> 
    <span> 
    <Counter /> 
    </span> 
</div> 

回答

1

是的,它会重新实例化

Couter组件
<div> 
    <Counter /> 
</div> 

<span> 
    <Counter /> 
</span> 

Reconciliation指定的过程说:

这将摧毁旧计数器并重新安装一个新的。

对于第二个例子中,它将比较<div>第一,没有变化,但是接下来的是相同的情况下如上述所以它也将remountCounter组件。

+0

谢谢。所以它是'Counter'组件的全新实例。 – Ben

+0

是的,因为它会摧毁它,然后重新安装。 –

0

From the docs

每当根元素有不同的类型,反应会推倒 老树和从头构建新树。从<a><img>,或从<Article><Comment>,或从<Button><div> - any 那些会导致完全重建。

所以是的,在这两种情况下,一个新类型的节点下的所有东西都将被完全重构。

工作演示

class Inner extends React.Component { 
 
    constructor(props) { 
 
     super(props); 
 
     console.log('Inner constructor called.') 
 
    } 
 

 
    render() { 
 
     return <p>{`<${this.props.tag}>`}</p>; 
 
    } 
 
} 
 

 
const Container = ({Tag}) => (
 
    <Tag> 
 
     <Inner tag={Tag} /> 
 
    </Tag> 
 
); 
 

 
class App extends React.Component { 
 
    constructor(props) { 
 
     super(props); 
 
     this.state = { 
 
      tag: 'div', 
 
     }; 
 
    } 
 

 
    changeTag =() => this.setState(state => state.tag === 'div' ? {tag: 'span'} : {tag: 'div'}); 
 

 
    render() { 
 
     return (
 
      <div> 
 
       <button onClick={this.changeTag}>Change tag</button> 
 
       <Container Tag={this.state.tag} /> 
 
      </div> 
 
     ); 
 
    } 
 
} 
 

 
ReactDOM.render(<App />, document.getElementById('root'));
<div id="root"><!--Filled by React--></div> 
 

 
<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>