簡體   English   中英

如何只修改react .map函數中的一個元素?

[英]How to modify only one element in a react .map function?

我有點新的反應,並且有點迷失在這里做什么。 我正在從firebase加載數據並使用.map函數呈現該對象的道具,以列出頁面上的所有“注釋”,這樣可以正常工作。 我還想調用一個允許用戶回復單個注釋的組件(即地圖中的一個特定元素),但正如此代碼所期望的,當單擊回復按鈕時,它會在該元素的每個元素下顯示被調用的組件。地圖,這是不可取的。 無論如何,在這種情況下,我可以只為地圖的一個元素調用組件嗎?

changeIsReply() {
  this.setState(
    {isReply: !this.state.isReply,}
  );
}    

  render() {

  return (
    <div>
    <ul className="list-group">
    {Object.values(this.props.commentInfo).map((data) =>
      data.map((secondData, i) =>
        <div className="commentHolder" key={i}>
            <p>{secondData.text}</p>
            <p>{secondData.category}</p>
            <p>{secondData.organization}</p>
            <button> UpButton </button> <br />
            <button> DownButton </button>
            <button onClick = {this.changeIsReply} > Reply </button>
            {this.state.isReply ? <SetComment id={secondData.key} /> : null}
        </div>
      )
    )}
    </ul>
    </div>
  )
}

那是因為您對所有評論都使用單一狀態。

<button onClick = {() => this.changeIsReply(secondData.key)} > Reply </button>

{this.state.isReply && this.state.clickedComment == {secondData.key} ? <SetComment id={secondData.key} /> : null}

並將changeIsReply()更改為:

changeIsReply(clickedId) {
    this.setState(
    {isReply: !this.state.isReply, clickedComment: clickedId}
);}

看看這是否有效。 不要忘記將新狀態添加到構造函數中。

您可以跟蹤哪個評論應該包含SetComment組件。

 constructor(props) { super(props); this.state = { // init commentReplyIds as empty array commentReplyIds : [], // ... rest of your state } } changeIsReply(commentId) { const newCommentReplyIds = [...this.state.commentReplyIds. commentId]; this.setState( {commentReplyIds: newCommentReplyIds} ); } render() { // in here I am using the data.text as the unique id of each comment, you can use other serializable value. return ( <div> <ul className="list-group"> {Object.values(this.props.commentInfo).map((data) => data.map((secondData, i) => <div className="commentHolder" key={i}> <p>{secondData.text}</p> <p>{secondData.category}</p> <p>{secondData.organization}</p> <button> UpButton </button> <br /> <button> DownButton </button> <button onClick = {() => this.changeIsReply(secondData.text)} > Reply </button> {this.state.commentReplyIds.includes(secondData.text) ? <SetComment id={secondData.key} /> : null} </div> ) )} </ul> </div> ) } 

使用此方法,您可以使用多個SetComment組件,在用戶單擊了回復注釋按鈕的不同注釋中。

你需要保持isReply成為一個數組數組,並根據點擊的注釋索引,只更新正確的值,如

state= {
   isReply: [[]]
}
changeIsReply(i, j) {
  var isReply = [...this.state.isReply]
  if(isReply[i] === undefined) {
    isReply.push([true]) = 
  } else {
    if(isReply[i][j] === undefined) {
      isReply[i].push(true)
    } else {
       isReply[i][j] = !isReply[i][j]
    }
  }
  this.setState(
    {isReply}
  );
}    

  render() {

  return (
    <div>
    <ul className="list-group">
    {Object.values(this.props.commentInfo).map((data, i) =>
      data.map((secondData, j) =>
        <div className="commentHolder" key={j}>
            <p>{secondData.text}</p>
            <p>{secondData.category}</p>
            <p>{secondData.organization}</p>
            <button> UpButton </button> <br />
            <button> DownButton </button>
            <button onClick = {() => this.changeIsReply(i, j)} > Reply </button>
            {this.state.isReply[i][j] ? <SetComment id={secondData.key} /> : null}
        </div>
      )
    )}
    </ul>
    </div>
  )
}

我建議把它分成兩部分。 CommentListComment組件。

評論-list.js

import Comment from './comment';

class CommentList extends Component{
    render(){
    return(
        <div>
        <ul className="list-group">
                {Object.values(this.props.commentInfo).map((data) =>
                data.map((secondData, i) =>
                    <Comment text={secondData.text} category={secondData.category} organization={secondData.organization} key={secondData.key} />
      )
        </ul>
      </div>
    )
  }
}

comment.js

class Comment extends Component {
    constructor(props){
    super(props);
    this.state = {
        isReply: false
    }
  }
  changeIsReply = () => {
    this.setState(
      {isReply: !this.state.isReply,}
    );
  }   
    render(){
    const {text, category, organization, key} = this.props;
    return(
      <div className="commentHolder" key={i}>
        <p>{text}</p>
        <p>{category}</p>
        <p>{organization}</p>
        <button> UpButton </button> <br />
        <button> DownButton </button>
        <button onClick = {this.changeIsReply} > Reply </button>
        {this.state.isReply ? <SetComment id={key} /> : null}
      </div>
    )
  }
}

export default Comment;

這樣,每個注釋都可以控制自己的狀態以及是否顯示SetComment組件。

嘗試制作更多組件,而不是將所有標記放在單個渲染方法中。 這也有助於組織代碼,以便將每組值映射到一個組件 ,我覺得這樣可以讓您更容易理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM