首页 > 解决方案 > 按钮单击呈现多个不需要的组件 React

问题描述

我的问题是:我有一个必须在应用程序中渲染 3 次的组件,并且该组件有一个按钮,该按钮应该使用新组件更新该组件。我在每个实例中都获取占位符组件,而不仅仅是触发事件的组件。我的代码:

class App extends Component {
  constructor(){
    super()
    this.state = {showCard : false,cards : []}
    this.buttonClick = this.buttonClick.bind(this)
  }

  buttonClick(ev){
    console.log(ev.target)
    const nextId = this.state.cards.length + 1
    this.setState({cards: this.state.cards.concat([nextId])})
    this.setState({showCard: true,})
  }

  render() {
    console.log(this)
    return (
      <div className="App">
        <h2>React Demo</h2>
          <ul className="container">
            <Contact key="0" text={"Contact 1"} buttonClick={this.buttonClick} showCard={this.state.showCard} cards={this.state.cards}/>
            <Contact key="1" text={"Contact 2"} buttonClick={this.buttonClick} showCard={this.state.showCard} cards={this.state.cards}/>
            <Contact key="2" text={"Contact 3"} buttonClick={this.buttonClick} showCard={this.state.showCard} cards={this.state.cards}/>
        </ul>
      </div>
    );
  }
}

function Contact(props){
    return <li>
            <h3>{props.text}</h3>
            <ul className="stack">
              <li><button id={props.text} type="button" className="block" onClick={e =>props.buttonClick(e)}>+</button></li>
              {props.cards.map(cardId => <Card key={props.text+cardId}/>)}
            </ul>
           </li>
}

function Card(){
  return <li><div className="card">Place Holder</div></li>
}

export default App;

我已经尝试使用showCard和映射进行条件渲染,如此处所示,在这两种情况下,组件的所有三个实例都被更新而不是正确的一个。我知道这是我在做的愚蠢的事情,我只是看不到它。提前致谢。

Ĵ

标签: javascriptreactjs

解决方案


更新代码:

const list = [
  {
    id : 0,
    title : "Contact 1",
    showCard : false,
    addCard : ()=> <Card key={"x"+count++}/>,
    cards : []
  },
  {
    id : 1,
    title : "Contact 2",
    showCard : false,
    addCard : ()=> <Card key={"y"+count++}/>,
    cards : []
  },
  {
    id : 2,
    title : "Contact 3",
    showCard : false,
    addCard : ()=> <Card key={"z"+count++}/>,
    cards : []
   }
]


let count = 0

class App extends Component {
  constructor(){
    super()
    this.state = {list : list}
    this.buttonClick = this.buttonClick.bind(this)
  }

  buttonClick(ev,id){
    let a0 = null
    for(let obj of this.state.list){
      if(obj.id === id){ 
        a0 = obj.addCard()
        obj.cards.push(a0)
      }
    }
    this.setState({list:this.state.list})
  }

  render() {
    return (
      <div className="App">
        <h2>React Demo</h2>
          <ul className="container">
            {this.state.list.map((item) =>
                <Contact key={item.title+item.id} text={item.title} buttonClick={this.buttonClick} showCard={item.showCard} id={item.id} cards={item.cards}/>
          )}

        </ul>
      </div>
    );
  }
}

function Contact(props){
    return <li>
            <h3>{props.text}</h3>
            <ul className="stack">
              <li><button id={props.text} type="button" className="block" onClick={e =>props.buttonClick(e,props.id)}>+</button></li>
              {props.cards.map((card)=> {
                return card || null
                })}
            </ul>
           </li>
}

function Card(){
  return <li><div className="card">Place Holder</div></li>
}

export default App;

正如 Jonas H建议的那样,我正在与 Contact 组件的所有三个实例共享状态。我只做了几个星期的 React,因此需要时间来解决这个问题。我的解决方案可能不是最佳的,但它确实有效,尽管它确实破坏了我的用户界面......但这是另一个任务。谢谢大家。

Ĵ

感谢@Jonas H


推荐阅读