代码之家  ›  专栏  ›  技术社区  ›  Joliet

按钮单击渲染多个不需要的组件响应

  •  0
  • Joliet  · 技术社区  · 6 年前

    我的问题是:我有一个组件必须在应用程序中呈现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 如图所示,在这两种情况下,组件的所有三个实例都会更新,而不是正确的实例。我知道我在做什么蠢事,我就是看不见。事先谢谢。

    J

    2 回复  |  直到 6 年前
        1
  •  0
  •   Joliet    6 年前

    更新代码:

    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;
    

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

    J

    感谢@jonas h

        2
  •  -2
  •   Sunil Kumar    6 年前

    应该组件更新() 方法可以解决你的问题

    使用shouldComponentUpdate()让react知道组件输出是否不受当前状态或属性更改的影响。默认行为是在每次状态更改时重新呈现,在大多数情况下,您应该依赖默认行为。 more

    shouldComponentUpdate(nextProps, nextState) {
       // should return either true or fase 
    
       // component should render on state changes or initial render
       if((JSON.stringify(nextState) !== JSON.stringify(this.state)) || (JSON.stringify(this.state) === (JSON.stringify({showCard : false,cards : []})) ) {
         return true;
       }
    
         return false;
    }
    

    把上面的方法放到代码中