提问人: 提问时间:1/27/2023 更新时间:1/28/2023 访问量:89
类组件 ReactJS - setTimeout 在类组件中获取错误值
Class Component ReactJS - setTimeout get wrong value in class component
问:
应用组件:
class App extends React.Component {
constructor() {
super();
this.state = {
user: 'Dan',
};
}
render() {
return (
<React.Fragment>
<label>
<b>Choose profile to view: </b>
<select
value={this.state.user}
onChange={e => this.setState({ user: e.target.value })}
>
<option value="Dan">Dan</option>
<option value="Sophie">Sophie</option>
<option value="Sunil">Sunil</option>
</select>
</label>
<h1>Welcome to {this.state.user}’s profile!</h1>
<p>
<ProfilePageClass user={this.state.user} />
<b> (class)</b>
</p>
</React.Fragment>
)
}
}
ProfilePageClass(问题就在这里):
class ProfilePageClass extends React.Component {
showMessage = () => {
alert('Followed ' + this.props.user); // This get wrong value (new props)
};
handleClick = () => {
setTimeout(this.showMessage, 6000); // This get wrong value (new props)
};
render() {
return <button onClick={this.handleClick}>Follow</button>;
}
}
setTimeout 不显示最初关注的用户对应的消息
我认为这是道具的问题,但我不确定。
谁能告诉我这是怎么回事?
答:
-1赞
saguirrews
1/27/2023
#1
很可能你的使用存在问题,你失去了对你希望展示的实际道具的引用。您可以将类似以下内容添加到父组件中:setTimeout
this.myRef = React.createRef();
这将生成一个 ref,您稍后可以将其传递给子组件。您可以按以下方式设置 refs 当前项目:
this.myRef.current = this.state.user
为了填充 ref。
评论
0赞
1/27/2023
嗨,@saguirrews,谢谢,但是,我需要更多细节来理解
-1赞
Mallikarjun M G
1/27/2023
#2
尝试此修改,因为可能没有自动绑定。handleClick
import React from "react";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
user: 'Dan',
};
}
render() {
return (
<React.Fragment>
<label>
<b>Choose profile to view: </b>
<select
value={this.state.user}
onChange={e => this.setState({ user: e.target.value })}
>
<option value="Dan">Dan</option>
<option value="Sophie">Sophie</option>
<option value="Sunil">Sunil</option>
</select>
</label>
<h1>Welcome to {this.state.user}’s profile!</h1>
<p>
<ProfilePageClass user={this.state.user} />
<b> (class)</b>
</p>
</React.Fragment>
)
}
}
个人资料提醒
class ProfilePageClass extends React.Component {
//Define a constructor here
constructor(props){
super(props)
// Bind handleClick , so that `this` will point to parent component when you pass to child
this.handleClick= this.handleClick.bind();
}
showMessage = () => {
alert('Followed ' + this.props.user); // This get value (new props)
};
handleClick = () => {
setTimeout(this.showMessage, 100); // This get value (new props)
};
render() {
return <button onClick={this.handleClick}>Follow</button>;
}
}
0赞
Bergi
1/27/2023
#3
与关键字无关。当应用状态更改时,组件实例会收到新值,并且在它们更改后运行的回调将访问新值。这有时是可取的,有时不是。this
props
setTimeout
这是函数组件和类
组件之间的区别之一。若要获取单击按钮时呈现的用户配置文件,需要在单击(或呈现)按钮时明确记住它:
class ProfilePageClass extends React.Component {
handleClick = () => {
const user = this.props.user;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
setTimeout(() => {
alert('Followed ' + this.props.user); // current value (wrong)
alert('Followed ' + user); // old value (expected)
}, 6000);
};
render() {
return <button onClick={this.handleClick}>Follow</button>;
}
}
使用函数组件,您不会出错(但是如果没有 useRef
,访问当前值几乎是不可能的):
function ProfilePageClass({user}) {
const handleClick = () => {
setTimeout(() => {
alert('Followed ' + user); // old value (expected)
}, 6000);
};
return <button onClick={this.handleClick}>Follow</button>;
}
评论
2赞
Bergi
1/27/2023
是的,箭头函数在 上形成一个闭包。请注意,在 JS 中,闭包甚至根本不捕获值(无论是引用值还是这些值的副本,甚至是深层副本/快照),它们捕获变量。虽然既不改变也不改变,所以这里等同于捕捉 indeed 的(参考)值。this
this
const user
this
1赞
Bergi
1/27/2023
它捕获实时变量,无论当前值(对象/基元)是什么。变量没有类型,您可以将基元分配给当前包含对象的变量,反之亦然。
2赞
Bergi
1/27/2023
就其本身而言,由于箭头函数的工作方式。this
1赞
Bergi
1/27/2023
是的,请参阅答案的第一段:问题是 React 正在改变组件实例。.props
1赞
Bergi
1/27/2023
是的,它们捕获当前渲染的所有蚂蚁不可变变量。唯一的出路是.const
useRef
评论