我有两个文件:TrainingGround.js 和 Rectangle.js。
TrainingGround.js
import React from 'react';
import { Rectangle, RectangleComponent } from './Rectangle';
export class TrainingGround extends React.Component {
constructor(props) {
super(props);
this.state = {
rect: new Rectangle(10, 20, 5, 10, 0),
};
this.rotate = this.rotate.bind(this);
}
rotate() {
this.state.rect.rotateDeg(45);
console.log(this.state.rect.vertices);
}
render() {
return (
<div onClick={this.rotate}>
<RectangleComponent
w={this.state.rect.boundingWidth}
h={this.state.rect.boundingHeight}
position={this.state.rect.center}
vertices={this.state.rect.vertices}
></RectangleComponent>
</div>
);
}
}
当我调用 this.state.rect.rotateDeg(45)
时,this.state.rect.vertices
的值被分配了一个新数组(即该数组不是简单的修改)。但是,这似乎不会触发 RectangleComponent
的重新渲染。我可以通过下方的 console.log()
声明确认此更改。
Rectangle.js
...
export class RectangleComponent extends React.Component {
get polygonStr() {
// Create str of vertices, e.g. '1px 2px, 3px 4px, ...'
const verticesStr = this.props.vertices.map((e) => e.map((f) => f + 'px').join(' ')).join(', ');
return `polygon(${verticesStr})`;
}
render() {
return (
<div
style={{
position: 'relative',
clipPath: this.polygonStr, // vertices should change, updating this value
backgroundColor: '#000',
width: this.props.w + 'px',
height: this.props.h + 'px',
top: this.props.position[1] + 'px',
left: this.props.position[0] + 'px',
}}
></div>
);
}
}
为什么在这种情况下组件没有更新?
这似乎是其他新 React 开发人员面临的常见问题。我已经查看了与此类似的其他问题,但我仍然在摸索为什么这不会更新。
我的理解是组件将在以下任一情况下重新渲染:
除了任何一个的可变对象(在我上面的例子中不应该是这种情况)。
答案 0 :(得分:1)
更改您的旋转方法以设置新状态而不是更改状态
rotate() {
// this.state.rect.rotateDeg(45); <-- Do not do this
const newRect = new Rectangle(10, 20, 5, 10, 45) //<-- Create new state
this.setState({rect: newRect}) //<-- Set new state
}
答案 1 :(得分:0)
试着像下面那样做
rotate() {
const rect ={...this.state.rect}
rect.rotateDeg(45);
this.setState({rect});
}
答案 2 :(得分:0)
您不能像以前那样通过链接更新任何 this.state
。
React 组件在两种情况下重新渲染自身:
一个。任何状态属性被更改(仅使用 this.setState 方法)
B.任何传递给这个组件的 props 都会改变。
在您的示例中,您最好执行以下操作:
this.state
内并正确更改(仅通过 this.setState
){
constructor(props) {
super(props);
this.state = {
angle: 0,
}
this.rectangle = new Rectangle(10, 20, 5, 10, 0);
}
rotate = (angle) => {
this.setState({ angle });
}
componentWillUpdate(nextProps, nextState) {
if (this.state.angle !== nextState.angle) {
this.rectangle.rotateDeg(nextState.angle);
}
}
}
使用 FC 和 hooks 会更容易。