React學習筆記(五) 狀態提升


狀態提升究竟是什么東西呢?別急,下面讓我們一步一步來看看究竟要怎么使用狀態提升

假設我們有這樣一個需求,提供兩個輸入框(分別屬於兩個組件),保證輸入框里面的內容同步

好,下面我們先來封裝一個輸入框組件 Input

class Input extends React.Component {
    constructor(props) {
        super(props)
        // 輸入框里的內容保存在組件的 state 當中
        this.state = { content: '' }
        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(e) {
        this.setState({ content: e.target.value })
    }

    render() {
        return (
            <input type='text' value={ this.state.content } onChange={ this.handleChange } />
        )
    }
}

然后我們另外定義一個組件 AllInput,在這個組件中包含兩個 Input 組件,這樣我們就得到兩個輸入框

class AllInput extends React.Component {
    constructor(props) {
        super(props)
    }
    
    render() {
        // 這里包含兩個 `Input`  組件
        return (
            <div>
            	<Input />
                <br /><br />
                <Input />
            </div>
        )
    }
}

好,下一個要解決的問題是怎么使兩個輸入框的內容同步

在兩個 Input 組件中,它們各自的內容保存在各自的 state 當中,要怎么做才能使兩個組件共享數據呢?

答案是 狀態提升,即將兩個組件需要共享的數據保存在共同的父組件中,然后子組件通過 props 獲取父組件數據

也就是說,我們可以將兩個子組件 Input 的數據保存在它們的父組件 AllInput 當中

我們先來看看怎么修改父組件的定義:

class AllInput extends React.Component {
    constructor(props) {
        super(props)
        // 在父組件中添加 state 對象,用於保存數據
        this.state = { content: '' }
        this.handleContentChange = this.handleContentChange.bind(this)
    }
    
    // 定義修改 state 的方法,通過 props 傳遞給子組件使用
    // 接收一個參數(新的數據)
    handleContentChange(newContent) {
        this.setState({ content: newContent })
    }
    
    render() {
        // 通過 props 將 state 和修改 state 的方法都傳遞給子組件
        return (
            <div>
            	<Input content={ this.state.content } onContentChange={ this.handleContentChange }/>
                <br /><br />
                <Input content={ this.state.content } onContentChange={ this.handleContentChange }/>
            </div>
        )
    }
}

然后我們再來修改子組件定義:

class Input extends React.Component {
    constructor(props) {
        super(props)
        // 數據可以不再保存在子組件的 state 當中
        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(e) {
        // 通過 props 獲取父組件的 setState(修改數據的方法)
        // 傳入一個參數(新的數據)
        this.props.onContentChange(e.target.value)
    }

    render() {
        // 通過 props 獲取父組件的 state(數據)
        return (
            <input type='text' value={ this.props.content } onChange={ this.handleChange } />
        )
    }
}

通過狀態提升,這樣就可以實現組件之間的數據共享啦,一份完整的可運行的代碼如下:

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone"></script>
</head>

<body>
    <div id="app"></div>

    <script type="text/babel">
        class Input extends React.Component {
            constructor(props) {
                super(props)
                this.handleChange = this.handleChange.bind(this)
            }

            handleChange(e) {
                this.props.onContentChange(e.target.value)
            }

            render() {
                return (
                    <input type='text' value={ this.props.content } onChange={ this.handleChange } />
                )
            }
        }
        
        class AllInput extends React.Component {
            constructor(props) {
                super(props)
                this.state = { content: '' }
                this.handleContentChange = this.handleContentChange.bind(this)
            }

            handleContentChange(newContent) {
                this.setState({ content: newContent })
            }

            render() {
                return (
                    <div>
                        <Input content={ this.state.content } onContentChange={ this.handleContentChange }/>
                        <br /><br />
                        <Input content={ this.state.content } onContentChange={ this.handleContentChange }/>
                    </div>
                )
            }
        }
        
        ReactDOM.render(
            <AllInput />,
            document.getElementById('app')
        )
    </script>
</body>

</html>

【 閱讀更多 React 系列文章,請看 React學習筆記


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM