React中是否有一种方法可以多次只执行渲染函数的一部分,而另一部分则继续初始执行



我正在React中创建一个游戏。基本说明:绵羊的图像从屏幕中央被"发射",它们被设置为动画,移动到边界。如果他们达到了,你就输了。如果你之前点击它们,它们就会消失,然后你继续。我做了所有的东西,除了计数器,它统计你点击了多少只羊。描述代码:

<MainComponent  // everything else inside it
renders <Component creating background/>
<Component creating sheep images
renders array of sheep images, with onClick,onAnimationEnd and other props.
that array is made of lot of same StyledComponents, in a for loop.
every StyledComponent is one sheep image. 
/>
/>

一切都如我所愿。页面加载时,绵羊开始从中间开火(有特定的延迟和速度),当我点击它们时,它们会消失,当它们到达边界时,游戏结束。但是,我不知道如何以及在哪里添加<CountScoreComponent/>。我曾尝试将其放在上述所有组件中进行渲染,但它要么不更新分数,要么更新它,但只在游戏结束时显示最终分数(我希望每次点击绵羊图像时它都会更改),要么更新分数并显示它,但随后所有内容都会重新渲染,整个图像阵列都会重新创建并重新启动。

因此,我理解React首先创建所有组件,然后立即创建整个绵羊图像阵列。根据我把它放在哪里,它也会立即用它的初始值创建<CountScoreComponent/>。如何在每次单击时动态更新该组件的状态(或其返回值),但同时保持初始阵列动画的执行(无需重新渲染和重新启动)?

编辑:代码:

class MainComponent extends React.Component {
render(){
return (
<React.Fragment>
<CreateEnvironment />
<SheepsStart />                      
</React.Fragment>
);
}
}
ReactDOM.render(<MainComponent/>, document.getElementById('root'));

绵羊启动.js

const animDuration = []; //gets populated with 100 random numbers
const positionLeft = []; //positions for KeyFrames, 100 numbers defined by external function call
const positionBottom = [];

export class SheepsStart extends React.Component { 
constructor(props){
super(props);
this.state = {gameOver:false};
this.handleAnimationEnd = this.handleAnimationEnd.bind(this);       
}   
handleAnimationEnd(){
this.setState({gameOver:true});
}
render(){
const arrayOfComponents = [];
for (let index = 0;index<100;index++){
if(this.state.gameOver === false){
arrayOfComponents.push(<CreateSheeps src={sheep} alt={`sheep-${index}`} 
style = {{animationDelay:`${index/2}s`}} left = {positionLeft[index]} bottom = {positionBottom[index]} 
time = {animDuration[index]} onAnimationEnd = {this.handleAnimationEnd}/>);
}
else {
alert("GAME OVER! ");
break;
}
}
return (
<React.Fragment>                        
{arrayOfComponents}                                 
</React.Fragment>
);
}

}

createSheeps.js

export class CreateSheeps extends React.Component { 
constructor(props){
super(props);
this.state = {left:this.props.left, bottom:this.props.bottom,    display:'inline'};
this.handleClickAnimation = this.handleClickAnimation.bind(this);                 
}    
handleClickAnimation(){
this.setState({display:'none'});
}     
render(){        
const sheepWantsToEscape = keyframes`
100% {
left:${this.state.left}%;
bottom:${this.state.bottom}%;
}
`        
const CreateSheeps = styled.img`
//some data
`
return (
<React.Fragment>
<CreateSheeps src = {this.props.src} style = {this.props.style} 
onClick = {this.handleClickAnimation} onAnimationEnd = {this.props.onAnimationEnd}/>         
</React.Fragment>   
)  
}

}

通过使用shouldComponentUpdate挂钩、PureComponentmemo将元素移动到防止更新的单独组件,可以防止元素被重新渲染。即:

const ComponentThatIsRarelyUpdated = memo(props => <ComponentThatNeedsToBeRarelyUpdated {...props}/>;
...
<CountScoreComponent/>
<ComponentThatIsRarelyUpdated propThatTriggersAnUpdate={...} />

在这种情况下,这是XY问题。实际问题是ComponentThatNeedsToBeRarelyUpdated的状态在重新渲染时会重置。它应该是有状态的并保持状态直到卸载,或者状态应该提升到父组件。

最有可能的是,亲本组件应该存储所有绵羊的状态。

最新更新