最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to set defaultValue, value={this.props.value}, and update the value of a text input with React? - Stack Overflo

programmeradmin5浏览0评论

Summary:

I'm attempting to make a blog with React and seem to have hit a snag in setting and updating a text field. I have the blog text and user name from a database and want to set the blog text in a text window for a given user. Then when the user types I also want to update that text.

Attempt:

If I set my textarea value={this.props.name} it will correctly set the value but won't update. If I set it to update with {this.state.value} then it starts off blank but will update correctly. I can find examples of how either set the default value or update the value. I can't figure out how to do both. Thank you in advance.

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,
    };
  },
  ponentDidMount: 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: There were some issues in my understanding between the distinction of a controlled and uncontrolled React ponent and the React lifecycle. Now the value is set in getInitialState and then updated appropriately in ponentWillReceiveProps. Thank you everyone!

Changes:

  • ponentDidMount -> ponentWillReceiveProps. This has to do with the React ponent lifecycle.
  • The text area defaultValue={this.props.name} has been changed to reflect the updated state value of value={this.state.value}.
  • this.state.value=this.props.value in the render function has been removed.
       // 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,
            };
          },
          ponentWillReceiveProps: function(nextProps) {
                console.log("ponentWillReceiveProps: " + nextProps.name);
                this.setState({value: nextProps.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() {
            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>
            );
          }
        });

Summary:

I'm attempting to make a blog with React and seem to have hit a snag in setting and updating a text field. I have the blog text and user name from a database and want to set the blog text in a text window for a given user. Then when the user types I also want to update that text.

Attempt:

If I set my textarea value={this.props.name} it will correctly set the value but won't update. If I set it to update with {this.state.value} then it starts off blank but will update correctly. I can find examples of how either set the default value or update the value. I can't figure out how to do both. Thank you in advance.

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,
    };
  },
  ponentDidMount: 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: There were some issues in my understanding between the distinction of a controlled and uncontrolled React ponent and the React lifecycle. Now the value is set in getInitialState and then updated appropriately in ponentWillReceiveProps. Thank you everyone!

Changes:

  • ponentDidMount -> ponentWillReceiveProps. This has to do with the React ponent lifecycle.
  • The text area defaultValue={this.props.name} has been changed to reflect the updated state value of value={this.state.value}.
  • this.state.value=this.props.value in the render function has been removed.
       // 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,
            };
          },
          ponentWillReceiveProps: function(nextProps) {
                console.log("ponentWillReceiveProps: " + nextProps.name);
                this.setState({value: nextProps.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() {
            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>
            );
          }
        });
Share Improve this question edited Oct 8, 2020 at 5:41 user128511 asked May 15, 2016 at 18:45 SaundersBSaundersB 6472 gold badges12 silver badges25 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

so, whenever you want to edit props, you have to set them in the local ponent state ( like you did in the getInitialState by setting value to the props ). Props are immutable, so setting the value or defaultValue of the input to the prop will/should not allow you to change the prop.

So below, what I have done is set value of the input to this.state.name, and this.state.name is set to this.props.name on initial state and whenever you call update, it will update the ponents state with whatever is typed in the input.

if you need to pass the name back to a parent ponent, then you need to pass in a function from the parent which you can then call from the child to inform the parent that the name value has changed, parent will then need to update the name which then gets passed back down to the child...this creates a 2 way data binding..

// 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,
    };
  },
  ponentWillReceiveProps: 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>
    );
  }
});

For forms in React:

The defaultValue and defaultChecked props are only used during initial render. If you need to update the value in a subsequent render, you will need to use a controlled ponent.

Docs on controlled ponents

Reading your code, there is no need to:

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

The job is already done by getInitialState. If you intend to have the state updated when the ponent receive new props you should write:

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

I think that, in your case, you should use this.state.value and that it is not well initialized because ponentWillReceiveProps was no implemented to update the ponent state when receiving a props.name value different from undefined.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论