Reactjs 在React中是否有一种方法可以只执行渲染函数的一部分多次,而另一部分继续执行初始执行?
我正在用React创建一个游戏。基本说明: 绵羊图像从屏幕中央“发射”,并设置动画以移动到边界。如果他们到了,你就输了。如果你以前点击过它们,它们就会消失,然后你继续。我做了所有的东西,除了计算你点击了多少只羊的计数器。 描述代码:Reactjs 在React中是否有一种方法可以只执行渲染函数的一部分多次,而另一部分继续执行初始执行?,reactjs,Reactjs,我正在用React创建一个游戏。基本说明: 绵羊图像从屏幕中央“发射”,并设置动画以移动到边界。如果他们到了,你就输了。如果你以前点击过它们,它们就会消失,然后你继续。我做了所有的东西,除了计算你点击了多少只羊的计数器。 描述代码: <MainComponent // everything else inside it renders <Component creating background/> <Component creating she
<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.
/>
/>
一切按我的意愿进行。在页面加载时,羊皮开始从中间射出(有特定的延迟和速度),当我点击它们时,它们消失,当它们到达边界时,游戏结束。但是,我不知道如何以及在哪里添加
。
我试着在上面的所有组件中渲染它,但它要么不更新分数,要么更新它,但只在游戏结束时显示最终分数(我希望每次单击绵羊图像时它都会更改),要么更新分数并显示,但随后一切都重新渲染,整个图像阵列被重新创建并重新启动
所以,我理解,React首先创建所有组件,然后立即创建整个绵羊图像数组。根据我把它放在哪里,它也会立即创建带有初始值的
。如何在每次单击时动态更新该组件的状态(或其返回值),但同时保持初始阵列动画的执行(无需重新渲染和重新启动)
编辑:
代码:
class MainComponent扩展了React.Component{
render(){
返回(
);
}
}
ReactDOM.render(,document.getElementById('root'));
sheepstart.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>
);
}
const animDuration=[]//用100个随机数填充
const positionLeft=[]//关键帧的位置,由外部函数调用定义的100个数字
const positionBottom=[];
导出类SheepStart扩展React.Component{
建造师(道具){
超级(道具);
this.state={gameOver:false};
this.handleAnimationEnd=this.handleAnimationEnd.bind(this);
}
handleAnimationEnd(){
this.setState({gameOver:true});
}
render(){
常量arrayOfComponents=[];
对于(让index=0;index一个元素可以通过使用shouldComponentUpdate
hook、PureComponent
或memo
将其移动到单独的组件来防止重新渲染。例如:
const ComponentThatIsRarelyUpdated = memo(props => <ComponentThatNeedsToBeRarelyUpdated {...props}/>;
...
<CountScoreComponent/>
<ComponentThatIsRarelyUpdated propThatTriggersAnUpdate={...} />
const component that arely updated=memo(props=>;
...
在这种情况下,这是XY问题。实际的问题是,需要自由更新的组件的状态在重新呈现时被重置。它应该是有状态的并保留状态,直到卸载为止,或者状态应该是
最有可能的父组件应该存储所有sheep的状态。您能解释/演示如何处理游戏状态吗?
具有状态{gameOver:true/false},该状态随AnimationEnd上的函数而改变(当sheep从边界百分比达到预定义值时)
有三个状态值:其中两个用于创建随机轨迹(这些数据被发送到关键帧),第三个是用于在单击图像时将图像的显示设置为“无”。单击图像连接到onClick event www.codesandbox.io/是一个很好的地方,可以轻松演示您的代码。您可以将图像放入自己的组件中,并尝试防止它们被重新渲染。我不确定这是否也适用于css动画,但[shouldComponentUpdate][1]是一个很好的开始-阅读本文,您就会明白为什么“PureComponent”可能是您的解决方案。[1]:好的,但当我将分数放入父级状态,并以某种方式将其连接到图像onClick时,当单击发生时,在setState更改父级状态后,它将重新渲染整个父级渲染函数,对吗?因此,它最终将重新渲染图像数组,这是我不想要的?没错。需要重新渲染父级以任何方式重新渲染。目标是不影响父组件重新渲染的子组件。这可以通过在父组件重新渲染时防止子组件被重新渲染,或者通过将状态移动到父级来实现,以便可以随时重新渲染子组件。这就是答案所暗示的。这就是不清楚您的sheep组件的外观的原因从你发布的伪代码中。这将非常有助于就需要更改的内容提供更具体的建议。我将提出一些有问题的代码。请等待几分钟。从我看到的情况来看,需要立即更新的组件是CreateSheeps
,它需要用正在更新的组件包装。移动整个如果游戏逻辑依赖CSS动画,则不能将ate(绵羊位置)添加到父级(如果您认真对待此应用程序,则可能需要将其更改为编程动画)。CreateSheeps需要在单击父级时接受回调以更新父级。
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>
)
}
const ComponentThatIsRarelyUpdated = memo(props => <ComponentThatNeedsToBeRarelyUpdated {...props}/>;
...
<CountScoreComponent/>
<ComponentThatIsRarelyUpdated propThatTriggersAnUpdate={...} />