【问题标题】:How do I stop my React application from continuously updating an element based on an input field?如何阻止我的 React 应用程序根据输入字段不断更新元素?
【发布时间】:2021-06-20 10:40:14
【问题描述】:

在我参与的这个程序中,我们目前正在开发一个“twitter 克隆”,但没有后端。我们正在尝试纯粹使用 React 使其看起来像 Twitter 并成为它的模型。

目前,我们有一个输入字段和一个“tweet”按钮。然而,发生的情况是我们输入一些内容,按下推文,然后每条推文都会随着输入字段的每次更改而更新。我们如何阻止它这样做,并且只显示我们按下推文时的每条推文?下面是我的 Feed 组件,下面是我的 Tweet 组件:

Feed.js:

// // import {Component} when building a class component
import React, {Component} from 'react';
// // importing our CSS file from src>css
import '../css/Feed.css';
import Tweets from './Tweets';

const GENERIC_Tweets_USERNAME = "Username" , GENERIC_Tweets_BODY = "Body", GENERIC_Tweets_TIMESTAMP = "Timestamp"; 
class Feed extends Component {
    // // constructor method available to us in class components
  constructor() {
    super();
    this.state = {
      tweets: [],
      username: GENERIC_Tweets_USERNAME,
      body: GENERIC_Tweets_BODY,
      timestamp: GENERIC_Tweets_TIMESTAMP,
    }
  }
  addTweets() {
    console.log(this.state.body);
 
    let tweets = this.state.tweets;
    tweets.push(
      {
        id: Date.now()
      }
    );
    this.setState(
      {
        tweets: this.state.tweets
      }
    );
  }
  handleTweet = (event) => {
    this.setState({body:event.target.value});
    console.log(this.state.body);
  }
  deleteTweets(id){
    let newTweetsArr = this.state.tweets;
    newTweetsArr.map((tweets, index) => {
      if (id === tweets.id) {
        newTweetsArr.splice(index,1);
      }
    });
    this.setState(
      {
        tweets: newTweetsArr
      }
    );
  }

  

  // // render method - render what is returned (JSX) onto the browser
  render() {
    return (
      <div>
        <div className="div-board">
          <div className="row">
          <div>
            <input onChange={this.handleTweet} placeholder="What's Happening?"></input>
        </div>
        <div>
     {this.state.description}
     <button className="btn btn-success add-button" onClick={this.addTweets.bind(this)}>
       Tweet
     </button> 
   </div>
            {
              this.state.tweets.map(tweets => {
                return <Tweets key={tweets.id} id={tweets.id} deleteHandler={this.deleteTweets.bind(this)} body={this.state.body} />
              })
            }
          </div>
        </div>
      </div>
    );
  }
}
export default Feed;

Tweets.js:

import React, {Component} from 'react';
import PropTypes from 'prop-types';
// const GENERIC_Tweets_USERNAME = "Username" , GENERIC_Tweets_BODY = "Body", GENERIC_Tweets_TIMESTAMP = "Timestamp"; 
class Tweets extends Component {
    // // ignore constructor method for now
  constructor(props) {
    super(props);
    this.usernameContent = React.createRef();
    this.bodyContent = React.createRef();
    this.timestampContent = React.createRef();
    this.state = {
      // username: GENERIC_Tweets_USERNAME,
      // body: GENERIC_Tweets_BODY,
      // timestamp: GENERIC_Tweets_TIMESTAMP,
      // editMode: false
    }
  }  
  // handleSave() {
  //   this.setState({
  //     username: this.usernameContent.current.value,
  //     body: this.bodyContent.current.value,
  //     timestamp: this.timestampContent.current.value,
  //     // editMode: false
  //   });
  // }
  handleDelete() {
    this.props.deleteHandler(this.props.id);
  }
//   // render method return JSX
render(){
    let usernameElement, bodyElement, timestampElement, buttonArea; 
    // if (this.state.editMode){
    //   usernameElement = <textarea ref={this.usernameContent} className="username-textarea" defaultValue={this.state.username}></textarea>;
    //   bodyElement = <textarea ref={this.bodyContent} className="body-textarea" defaultValue={this.state.body}></textarea>;
    //   timestampElement = <textarea ref={this.timestampContent} className="timestamp-textarea" defaultValue={this.state.timestamp}></textarea>;
    //   buttonArea = <div><button className="btn btn-primary" onClick={this.handleSave.bind(this)}>Save</button></div>;
    // }
    // else{
      usernameElement = <h5 className="card-username">{this.props.username}</h5>;
      bodyElement = <p>{this.props.body}</p>; 
      console.log(this.props);
      timestampElement = <p>{this.props.timestamp}</p>;
      buttonArea = <div>
      <button className="btn btn-danger" onClick={this.handleDelete.bind(this)}>Delete</button>
      </div>;
    // }
    return (
      <div className='col-sm-6'>
        <div className="card card-view">
          <div className="card-synopsis">
                {usernameElement}
                {bodyElement}
                {timestampElement}
                {buttonArea}
          </div>
        </div>
    </div>
    );
  }
}
// Tweets.defaultProps = {
//     username: "Username",
//    body: "Body",
//     timestamp: "Timestamp",
  // };
  Tweets.propTypes = {
    username: PropTypes.string
  };
  export default Tweets;```

【问题讨论】:

    标签: javascript reactjs twitter


    【解决方案1】:

    首先,更新你的函数,添加body参数并从现有的body中创建一个新数组,而不是改变它。此外,如果您将函数编写为匿名函数,则不必将 this 绑定到它(在 render() 函数中)。:

     addTweets = () => {
        this.setState({
            tweets: this.state.tweets.concat({  id: Date.now(), body: this.state.body }),
            body: ''
          });
      }
    

    然后,更正您的 render() 函数:

     {
                  this.state.tweets.map(tweets => {
                    return <Tweets key={tweets.id} id={tweets.id} deleteHandler={this.deleteTweets.bind(this)} body={tweets.body} />
                  })
      }
    

    【讨论】:

    • 效果很好!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多