我的问题是:我有一个必须在应用程序中渲染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
答案 0 :(得分:0)
更新的代码:
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几周,所以花了很多时间解决这个问题。我的解决方案可能不是最佳解决方案,但它确实有效,尽管确实破坏了我的用户界面……但这是另一个任务。谢谢大家。
J
感谢@Jonas H
答案 1 :(得分:-2)
shouldComponentUpdate()方法将解决您的问题
使用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;
}
将上述方法放入您的代码