首页 文章

如何设置defaultValue,value = {this.props.value},并使用React更新文本输入的值?

提问于
浏览
3

Summary:

我正在尝试用React创建一个博客,似乎在设置和更新文本字段方面遇到了麻烦 . 我有来自数据库的博客文本和用户名,并希望在给定用户的文本窗口中设置博客文本 . 然后当用户输入时我也想更新该文本 .

Attempt:

如果我设置我的textarea值= {this.props.name} 它将正确设置值但不会更新 . 如果我将其设置为使用 {this.state.value} 进行更新,则它将从空白处开始,但会正确更新 . 我可以找到如何设置默认值或更新值的示例 . 我无法弄清楚如何做到这两点 . 先感谢您 .

ClickScreen React Component Call within App

<ClickScreen
    setClicks={this.setClicks}
    setUsername={this.setUsername}
    setBlog={this.setBlog}
    onLogout={this.onLogout}
    counter={this.state.counter}
    blogtext={this.state.blogtext}
    username={this.state.username}
/>

BlogEntry React Component Call within ClickScreen Page:

<EditBlog name={this.props.blogtext} username={this.props.username} ></EditBlog>

EditBlog React Component

// Allows a user to edit a blog entry.
var EditBlog = React.createClass({
  displayName: 'Editor',
  propTypes: {
    name: React.PropTypes.string.isRequired
  },
  getInitialState: function() { 
    console.log("getInitialState value: " + this.props.name);
    return {
      value: this.props.name,
    };
  },
  componentDidMount: function() {
         this.setState({value: this.props.name});
  },
  handleChange: function(event) {
    console.log("changing the text area to: " + event.target.value)
    this.setState({value: event.target.value});
  },
  updateBlogText: function() {
        ajax('update_blog.php', { blogtext: this.value, username: this.props.username }, function(response) {
            console.log("Updating blog text to: " + this.state.value + " with user: " + this.props.username);

            if (response.result === 'success') {
                console.log("Success!");
                //this.props.setClicks(response.counter, response.username, response.blogtext);
                //this.props.setUsername(response.username);
                //this.props.setBlog(response.blogtext);
            }
            else if (response.result === 'error') {
                alert('Error: ' + response.msg);
                console.log("Error!");
            }
            else {
                alert('Response message has no result attribute.');
            }
        }.bind(this));
        console.log("Click button clicked");
    },
  render: function() {
    console.log("this.state.value: " + this.state.value)
    console.log("this.state.value blogtext: " + this.props.name);
    this.state.value = this.props.value;
    return (
        <div>
            <h2>Blog Entry</h2>
            <center>
              <form id="noter-save-form" method="POST">
                <textarea id="noter-text-area" name="textarea"  onChange={this.handleChange} defaultValue={this.props.name}></textarea>
                <input type="submit" value="Save" onClick={this.updateBlogText}/>
              </form>
            </center>
        </div>
    );
  }
});

Update: 我在理解受控和非受控React组件的区别与React生命周期之间存在一些问题 . 现在,该值在getInitialState中设置,然后在componentWillReceiveProps中进行适当更新 . 谢谢大家!

变化:

  • componentDidMount - > componentWillReceiveProps . 这与React组件生命周期有关 .

  • 文本区域 defaultValue={this.props.name} 已更改为反映 value={this.state.value} 的更新状态值 .
    已删除渲染功能中的

  • this.state.value=this.props.value .

//允许用户编辑博客条目 . var EditBlog = React.createClass({displayName:'Editor',propTypes:{name:React.PropTypes.string.isRequired},getInitialState:function(){console.log(“getInitialState value:”this.props.name); return {value:this.props.name,};},componentWillReceiveProps:function(nextProps){console.log(“componentWillReceiveProps:”nextProps.name); this.setState({value:nextProps.name});},handleChange :function(event){console.log(“将文本区域更改为:”event.target.value); this.setState({value:event.target.value});},updateBlogText:function(){ajax( 'update_blog.php',{blogtext:this.value,username:this.props.username},function(response){console.log(“将博客文本更新为:”this.state.value“与用户:”this . props.username);

if (response.result === 'success') {
                console.log("Success!");
                //this.props.setClicks(response.counter, response.username, response.blogtext);
                //this.props.setUsername(response.username);
                //this.props.setBlog(response.blogtext);
            }
            else if (response.result === 'error') {
                alert('Error: ' + response.msg);
                console.log("Error!");
            }
            else {
                alert('Response message has no result attribute.');
            }
        }.bind(this));
        console.log("Click button clicked");
    },
  render: function() {
    return (
        <div>
            <h2>Blog Entry</h2>
            <center>
              <form id="noter-save-form" method="POST">
                <textarea id="noter-text-area" name="textarea"  onChange={this.handleChange} value={this.state.value}></textarea>
                <input type="submit" value="Save" onClick={this.updateBlogText}/>
              </form>
            </center>
        </div>
    );
  }
});

3 回答

  • 2

    所以,每当你想编辑道具时,你必须将它们设置为本地组件状态(就像你在getInitialState中通过设置值到道具那样) . 道具是不可变的,因此将prop的输入值或defaultValue设置为/不应该允许您更改道具 .

    下面,我所做的是设置this.state.name的输入值,并且this.state.name在初始状态下设置为this.props.name,每当调用update时,它将更新组件状态输入中键入的内容 .

    如果您需要将名称传递回父组件,那么您需要从父项传入一个函数,然后您可以从子项调用该函数以通知父项名称值已更改,父项将需要更新然后将名称传递回子项...这将创建一个双向数据绑定..

    // Allows a user to edit a blog entry.
    var EditBlog = React.createClass({
      displayName: 'Editor',
      propTypes: {
        name: React.PropTypes.string.isRequired
      },
      getInitialState: function() { 
        console.log("getInitialState value: " + this.props.name);
        return {
          value: this.props.name,
        };
      },
      componentWillReceiveProps: function ( newProps ) {
        this.setState( { value:newProps.name } );
      }
      handleChange: function(event) {
        console.log("changing the text area to: " + event.target.value)
        this.setState({value: event.target.value});
      },
      updateBlogText: function() {
            ajax('update_blog.php', { blogtext: this.value, username: this.props.username }, function(response) {
                console.log("Updating blog text to: " + this.state.value + " with user: " + this.props.username);
    
                if (response.result === 'success') {
                    console.log("Success!");
                    //this.props.setClicks(response.counter, response.username, response.blogtext);
                    //this.props.setUsername(response.username);
                    //this.props.setBlog(response.blogtext);
                }
                else if (response.result === 'error') {
                    alert('Error: ' + response.msg);
                    console.log("Error!");
                }
                else {
                    alert('Response message has no result attribute.');
                }
            }.bind(this));
            console.log("Click button clicked");
        },
      render: function() {
        console.log("this.state.value: " + this.state.value)
        console.log("this.state.value blogtext: " + this.props.name);
        this.state.value = this.props.value;
        return (
            <div>
                <h2>Blog Entry</h2>
                <center>
                  <form id="noter-save-form" method="POST">
                    <textarea id="noter-text-area" name="textarea"  onChange={this.handleChange} value={value}></textarea>
                    <input type="submit" value="Save" onClick={this.updateBlogText}/>
                  </form>
                </center>
            </div>
        );
      }
    });
    
  • 2

    对于React中的表单:

    defaultValue和defaultChecked道具仅在初始渲染期间使用 . 如果需要更新后续渲染中的值,则需要使用受控组件 .

    Docs on controlled components

  • 3

    阅读您的代码,没有必要:

    componentDidMount: function() {
        this.setState({value: this.props.name});
    },
    

    该工作已由 getInitialState 完成 . 如果您打算在组件接收新道具时更新状态,则应编写:

    componentWillReceiveProps: function(nextProps) {
        this.setState({value: nextProps.name});
    },
    

    我认为,在您的情况下,您应该使用 this.state.value 并且它没有很好地初始化,因为 componentWillReceiveProps 没有实现在接收 undefined 值不同于 undefined 时更新组件状态 .

相关问题