施杰龙 發表於 2019-8-8 13:20:00

React学习笔记(五) 状态提升

<p>状态提升究竟是什么东西呢?别急,下面让我们一步一步来看看究竟要怎么使用状态提升</p>
<p>假设我们有这样一个需求,提供两个输入框(分别属于两个组件),保证输入框里面的内容同步</p>
<p>好,下面我们先来封装一个输入框组件 <code>Input</code></p>
<pre><code class="language-jsx">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 (
            &lt;input type='text' value={ this.state.content } onChange={ this.handleChange } /&gt;
      )
    }
}
</code></pre>
<p>然后我们另外定义一个组件 <code>AllInput</code>,在这个组件中包含两个 <code>Input</code>组件,这样我们就得到两个输入框</p>
<pre><code class="language-jsx">class AllInput extends React.Component {
    constructor(props) {
      super(props)
    }
   
    render() {
      // 这里包含两个 `Input`组件
      return (
            &lt;div&gt;
                    &lt;Input /&gt;
                &lt;br /&gt;&lt;br /&gt;
                &lt;Input /&gt;
            &lt;/div&gt;
      )
    }
}
</code></pre>
<p>好,下一个要解决的问题是怎么使两个输入框的内容同步</p>
<p>在两个 <code>Input</code>组件中,它们各自的内容保存在各自的 state 当中,要怎么做才能使两个组件共享数据呢?</p>
<p>答案是 <strong>状态提升</strong>,即将两个组件需要共享的数据保存在共同的父组件中,然后子组件通过 props 获取父组件数据</p>
<p>也就是说,我们可以将两个子组件 <code>Input</code> 的数据保存在它们的父组件<code>AllInput</code> 当中</p>
<p>我们先来看看怎么修改父组件的定义:</p>
<pre><code class="language-jsx">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 (
            &lt;div&gt;
                    &lt;Input content={ this.state.content } onContentChange={ this.handleContentChange }/&gt;
                &lt;br /&gt;&lt;br /&gt;
                &lt;Input content={ this.state.content } onContentChange={ this.handleContentChange }/&gt;
            &lt;/div&gt;
      )
    }
}
</code></pre>
<p>然后我们再来修改子组件定义:</p>
<pre><code class="language-jsx">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 (
            &lt;input type='text' value={ this.props.content } onChange={ this.handleChange } /&gt;
      )
    }
}
</code></pre>
<p>通过状态提升,这样就可以实现组件之间的数据共享啦,一份完整的可运行的代码如下:</p>
<pre><code class="language-jsx">&lt;!DOCTYPE html&gt;
&lt;html&gt;

&lt;head&gt;
    &lt;title&gt;Demo&lt;/title&gt;
    &lt;script src="https://unpkg.com/react@16/umd/react.development.js"&gt;&lt;/script&gt;
    &lt;script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"&gt;&lt;/script&gt;
    &lt;script src="https://unpkg.com/babel-standalone"&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id="app"&gt;&lt;/div&gt;

    &lt;script type="text/babel"&gt;
      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 (
                  &lt;input type='text' value={ this.props.content } onChange={ this.handleChange } /&gt;
                )
            }
      }
      
      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 (
                  &lt;div&gt;
                        &lt;Input content={ this.state.content } onContentChange={ this.handleContentChange }/&gt;
                        &lt;br /&gt;&lt;br /&gt;
                        &lt;Input content={ this.state.content } onContentChange={ this.handleContentChange }/&gt;
                  &lt;/div&gt;
                )
            }
      }
      
      ReactDOM.render(
            &lt;AllInput /&gt;,
            document.getElementById('app')
      )
    &lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;
</code></pre>
<p>【 阅读更多 React 系列文章,请看 React学习笔记 】</p>


</div>
<div id="MySignature" role="contentinfo">
    版权声明:本博客属于个人维护博客,未经博主允许不得转载其中文章。<br><br>
来源:https://www.cnblogs.com/wsmrzx/p/11320571.html
頁: [1]
查看完整版本: React学习笔记(五) 状态提升