ReactDOM.render(<App />, document.getElementById('root'));
// List.js import React, { Component } from 'react'; import { ActionButton } from './ActionButton'; export class List extends Component { constructor(props) { super(props); this.state = { items: [ { id: 1, title: "Item 1" }, { id: 2, title: "Item 2" }, { id: 3, title: "Item 3" }, { id: 4, title: "Item 4" }, { id: 5, title: "Item 5" }, ] }; } reverse = () => { this.setState({ items: this.state.items.reverse() }); } render() { console.log("Render List Component"); return ( <div className="list-container"> <ActionButton callback={this.reverse} /> <ul> {this.state.items.map(item => { return <li key={item.id}> {item.title} </li> })} </ul> </div> ); } } // ActionButton.js import React, { Component } from 'react'; export class ActionButton extends Component { render() { console.log("Render ActionButton Component"); return ( <button onClick={this.props.callback}>Click me</button> ); } }
import React from 'react'; import './App.css'; import { List } from './List'; function App() { console.log("Render App Component"); return ( <div className="App"> <h1>Reconciliation Process</h1> <List /> </div> ); } export default App;
Render App Component Render List Component Render ActionButton Component
<ul id="list"> {this.state.items.map(item => { return <li key={item.id}> {item.title} </li> })} </ul>
document.getElementById("list").classList.add("message")
همانطور که مشخص است کد فوق کلاسی با نام message را به عنصر ul اضافه کرده است:
.message { border: 1px solid green; padding: 2rem; }
اکنون وقتی بر روی دکمه Click me کلیک کنیم، محتوای درون کامپوننت فوق تغییر پیدا میکند، اما عنصر ul همچنان دارای کلاس message است؛ دلیل آن نیز همانطور که عنوان شد این است که React محتوای تولید شده توسط کامپوننت List را با Virtual DOM خودش مقایسه میکند و چون از لحاظ ساختار DOM با هم برابر هستند تغییری در ساختار خروجی کامپوننت ایجاد نمیکند و فقط قسمتهایی را که تغییر کردهاند، بروزرسانی خواهد کرد.
اکنون کامپوننت فوق را اینگونه تغییر خواهیم داد:
import React, { Component } from 'react'; import { ActionButton } from './ActionButton'; export class List extends Component { constructor(props) { // as before } reverse = () => { this.setState({ items: this.state.items.reverse(), wrapInDiv: true }); } generateElement = () => { const list = <ul id="list"> {this.state.items.map(item => { return <li key={item.id}> {item.title} </li> })} </ul>; return this.state.wrapInDiv ? <div>{list}</div> : list; } render() { console.log("Render List Component"); return ( <div className="list-container"> <ActionButton callback={this.reverse} /> {this.generateElement()} </div> ); } }