Javascript 反应:“this”在组件函数中未定义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33973648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React: "this" is undefined inside a component function
提问by Maximus S
class PlayerControls extends React.Component {
constructor(props) {
super(props)
this.state = {
loopActive: false,
shuffleActive: false,
}
}
render() {
var shuffleClassName = this.state.toggleActive ? "player-control-icon active" : "player-control-icon"
return (
<div className="player-controls">
<FontAwesome
className="player-control-icon"
name='refresh'
onClick={this.onToggleLoop}
spin={this.state.loopActive}
/>
<FontAwesome
className={shuffleClassName}
name='random'
onClick={this.onToggleShuffle}
/>
</div>
);
}
onToggleLoop(event) {
// "this is undefined??" <--- here
this.setState({loopActive: !this.state.loopActive})
this.props.onToggleLoop()
}
I want to update loopActive
state on toggle, but this
object is undefined in the handler. According to the tutorial doc, I this
should refer to the component. Am I missing something?
我想loopActive
在切换时更新状态,但this
处理程序中未定义对象。根据教程文档,我this
应该参考组件。我错过了什么吗?
回答by Ivan
ES6 React.Component doesn't auto bind methods to itself. You need to bind them yourself in constructor. Like this:
ES6 React.Component 不会自动将方法绑定到自身。您需要自己在构造函数中绑定它们。像这样:
constructor (props){
super(props);
this.state = {
loopActive: false,
shuffleActive: false,
};
this.onToggleLoop = this.onToggleLoop.bind(this);
}
回答by J. Mark Stevens
There are a couple of ways.
有几种方法。
One is to add
this.onToggleLoop = this.onToggleLoop.bind(this);
in the constructor.
一种是this.onToggleLoop = this.onToggleLoop.bind(this);
在构造函数中添加
。
Another is arrow functions
onToggleLoop = (event) => {...}
.
另一个是箭头函数
onToggleLoop = (event) => {...}
。
And then there is onClick={this.onToggleLoop.bind(this)}
.
然后是onClick={this.onToggleLoop.bind(this)}
。
回答by ShaTin
Write your function this way:
这样写你的函数:
onToggleLoop = (event) => {
this.setState({loopActive: !this.state.loopActive})
this.props.onToggleLoop()
}
the binding for the keyword this is the same outside and inside the fat arrow function. This is different than functions declared with function, which can bind this to another object upon invocation. Maintaining the this binding is very convenient for operations like mapping: this.items.map(x => this.doSomethingWith(x)).
关键字 this 的绑定在胖箭头函数的外部和内部是相同的。这与使用 function 声明的函数不同,后者可以在调用时将 this 绑定到另一个对象。维护 this 绑定对于映射之类的操作非常方便:this.items.map(x => this.doSomethingWith(x))。
回答by duhaime
I ran into a similar bind in a render function and ended up passing the context of this
in the following way:
我在渲染函数中遇到了类似的绑定,最终this
以下列方式传递了 的上下文:
{someList.map(function(listItem) {
// your code
}, this)}
I've also used:
我也用过:
{someList.map((listItem, index) =>
<div onClick={this.someFunction.bind(this, listItem)} />
)}
回答by Jakub Kutrzeba
You should notice that this
depends on how function is invoked
ie: when a function is called as a method of an object, its this
is set to the object the method is called on.
您应该注意到这this
取决于函数的调用方式,即:当一个函数作为this
对象的方法被调用时,它被设置为调用该方法的对象。
this
is accessible in JSX context as your component object, so you can call your desired method inline as this
method.
this
可以在 JSX 上下文中作为组件对象访问,因此您可以将所需的方法作为this
方法内联调用。
If you just pass reference to function/method, it seems that react will invoke it as independent function.
如果您只是传递对函数/方法的引用,则 react 似乎会将其作为独立函数调用。
onClick={this.onToggleLoop} // Here you just passing reference, React will invoke it as independent function and this will be undefined
onClick={()=>this.onToggleLoop()} // Here you invoking your desired function as method of this, and this in that function will be set to object from that function is called ie: your component object
回答by Henry Jacob
If you are using babel, you bind 'this' using ES7 bind operator https://babeljs.io/docs/en/babel-plugin-transform-function-bind#auto-self-binding
如果您使用 babel,则使用 ES7 绑定运算符https://babeljs.io/docs/en/babel-plugin-transform-function-bind#auto-self-binding绑定“this”
export default class SignupPage extends React.Component {
constructor(props) {
super(props);
}
handleSubmit(e) {
e.preventDefault();
const data = {
email: this.refs.email.value,
}
}
render() {
const {errors} = this.props;
return (
<div className="view-container registrations new">
<main>
<form id="sign_up_form" onSubmit={::this.handleSubmit}>
<div className="field">
<input ref="email" id="user_email" type="email" placeholder="Email" />
</div>
<div className="field">
<input ref="password" id="user_password" type="new-password" placeholder="Password" />
</div>
<button type="submit">Sign up</button>
</form>
</main>
</div>
)
}
}
回答by Alex
in my case this was the solution = () => {}
就我而言,这是解决方案= () => {}
methodName = (params) => {
//your code here with this.something
}
回答by GWorking
In my case, for a stateless component that received the ref with forwardRef, I had to do what it is said here https://itnext.io/reusing-the-ref-from-forwardref-with-react-hooks-4ce9df693dd
就我而言,对于接收带有 forwardRef 的 ref 的无状态组件,我必须按照此处所说的进行操作https://itnext.io/reusing-the-ref-from-forwardref-with-react-hooks-4ce9df693dd
From this (onClick doesn't have access to the equivalent of 'this')
从此(onClick 无法访问等效于“this”的内容)
const Com = forwardRef((props, ref) => {
return <input ref={ref} onClick={() => {console.log(ref.current} } />
})
To this (it works)
对此(它有效)
const useCombinedRefs = (...refs) => {
const targetRef = React.useRef()
useEffect(() => {
refs.forEach(ref => {
if (!ref) return
if (typeof ref === 'function') ref(targetRef.current)
else ref.current = targetRef.current
})
}, [refs])
return targetRef
}
const Com = forwardRef((props, ref) => {
const innerRef = useRef()
const combinedRef = useCombinedRefs(ref, innerRef)
return <input ref={combinedRef } onClick={() => {console.log(combinedRef .current} } />
})
回答by Guchelkaben
If you call your created methodin the lifecycle methods like componentDidMount... then you can only use the this.onToggleLoop = this.onToogleLoop.bind(this)
and the fat arrow function onToggleLoop = (event) => {...}
.
如果您在生命周期方法(如 componentDidMount...)中调用您创建的方法,那么您只能使用 thethis.onToggleLoop = this.onToogleLoop.bind(this)
和 fat arrow function onToggleLoop = (event) => {...}
。
The normal approach of the declaration of a function in the constructor wont work because the lifecycle methods are called earlier.
在构造函数中声明函数的正常方法将不起作用,因为生命周期方法被调用得更早。