React如何能够抑制输入字段值的变化?

时间:2016-03-28 17:49:43

标签: javascript reactjs

我经历了詹姆斯·尼尔森的Learn React.js (without JSX)系列。本系列介绍了使用React实现的表单,并显示输入字段是有效只读的,然后继续解释如何正确更改值。这是关于如何这样做的问题。相反,我想了解React如何防止值发生变化。

以下代码(也在jsfiddle中)是SSCCE:

<!doctype html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
  </head>
  <body>
    <div>
      <h3>simple HTML form (no ReactJS)</h3>
      <form>
        <input type='text' value placeholder='please enter your name'>
      </form>
    </div>
    <div id='react-app'>
      <script type='text/javascript'>
       const rce = React.createElement.bind(React);
       const rcc = React.createClass.bind(React);

       const ContactForm = rcc({
         propTypes: {
           value: React.PropTypes.object.isRequired,
         },
         render: function() {
           return rce('form', {}
                    , rce('input', {type: 'text'
                                  , placeholder: 'please enter your name'
                                  , value: this.props.value.name
                                  , onInput: function(se) {
                                    console.log(se.target.value);
                                  }}))}
         , componentWillMount       : function () {console.log('componentWillMount');}
         , componentDidMount        : function () {console.log('componentDidMount');}
         , componentWillReceiveProps: function () {console.log('componentWillReceiveProps');}
         , shouldComponentUpdate    : function () {console.log('shouldComponentUpdate');}
         , componentWillUpdate      : function () {console.log('componentWillUpdate');}             
         , componentDidUpdate       : function () {console.log('componentDidUpdate');}             
         , componentWillUnmount     : function () {console.log('componentWillUnmount');}
       });

       const ContactView = rcc({

         propTypes: {
           newContact: React.PropTypes.object.isRequired,
         }
         ,render: function () {
           console.log('render called');
           return rce('div', {}
                    , rce('h3', {}, 'why doesn\'t the input field value change?')
               , rce(ContactForm, {
                 value: this.props.newContact
               }))
         }
       });

       var reactApp = rce(ContactView, {newContact: {name: ''}});
       ReactDOM.render(reactApp, document.getElementById('react-app'));
      </script>
  </body>
</html>

上面的代码生成两个html表单:一个用简单的HTML创建,另一个用ReactJS创建。呈现的元素是相同的:

对于简单的HTML表单:

enter image description here

对于使用ReactJS创建的HTML表单:

enter image description here

我正在控制台上为每个被调用的组件生命周期方法记录消息。唯一似乎被调用的是rendercomponentWillMountcomponentDidMount(仅在开头)。在输入文本字段中输入击键时,不会调用后续生命周期方法。

所以我的问题是:假设没有调用其他生命周期方法,ReactJS如何管理以防止输入字段值发生变化,因为其DOM表示 相同 一个简单的HTML表单输入字段(当我在输入字段中键入时,我的浏览器中显示的值确实确实改变了)?

1 个答案:

答案 0 :(得分:4)

React使用virtual DOM的概念。它的作用是“虚拟地”跟踪变化,并用这种抽象取代“真正的”DOM。

当(重新)渲染组件时,它将虚拟DOM映射到“真实”DOM。将输入字段值限制为通过props收到的值后,它不会更改(因为您不会更改props)。

如果您希望将值与您输入的内容保持同步,则可以将值绑定到组件state

关于你的第二个问题,我没有完全关注,但你可能想看看component's lifecycle。这使您可以在发生某些更改时控制组件(例如,传递新的道具)。

更新

由于我认为我不清楚,请让我详细说明一下。

根据docs

<input type="text" name="title" value="Untitled" />

这将使用值Untitled呈现输入已初始化。当用户更新输入时,节点的value 属性将更改。但是,node.getAttribute('value')仍将返回初始化时使用的值Untitled

[属性与价值可能让我感到困惑。 Here's an explanatory post.]

与HTML不同,React组件必须在任何时间点表示视图的状态,而不仅仅是在初始化时。例如,在React中:

render: function() {
  return <input type="text" name="title" value="Untitled" />;
}

由于此方法在任何时间点描述视图,因此文本输入的值始终Untitled