![](/img/trans.png)
[英]Event Handler (prop) passed to child component cannot be called react native
[英]Function bound to React Component Cannot Be Passed to Child Component and Rebound
我在这个上下文问题上遇到了麻烦:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Foo extends Component {
constructor(props) {
super(props)
this.state = {
error: false
}
}
render() {
const { handleChange } = this.props;
let _handleChange = handleChange.bind(this);
return (
<div>
<input type='file' onChange={_handleChange} id='input'/>
<label htmlFor='input'> Upload </label>
{this.state.error && <span>{this.state.errorMessage}</span>}
</div>
)
}
}
class FooClosure extends Component {
handleChange = (event) => {
let self = this // this will always be FooClosure
debugger // local this context will be Foo
this.setState({ error: true, errorMessage: 'Some error happened'})
}
render() {
return (
<div>
<Foo handleChange={this.handleChange} />
</div>
)
}
}
class App extends Component {
render() {
return (
<div className="App">
<FooClosure />
</div>
);
}
}
export default App;
我正在尝试在父组件中定义的函数内使用 setState,该函数被绑定在子组件中。 我对 Javascript 的理解意味着this
将成为子组件,但this.setState
始终在 FooClosure 的上下文中执行。 谁能帮我理解为什么会这样?
我可以通过定义handleChange = (event, self) => ...
轻松解决这个问题handleChange = (event, self) => ...
但我认为我不应该这样做。
你应该这样写。
class Foo extends Component {
render() {
return (
<div>
<input type='file' onChange={this.props.handleChange} id='input'/>
<label htmlFor='input'> Upload </label>
{this.props.error && <span>{this.props.errorMessage}</span>}
</div>
)
}
}
class FooClosure extends Component {
constructor(props) {
super(props);
this.state = {error: false, errorMessage: ''};
}
handleChange = (event) => {
this.setState({ error: true, errorMessage: 'Some error happened'})
}
render() {
return (
<div>
<Foo handleChange={this.handleChange.bind(this)} error={this.state.error} errorMessage={this.state.errorMessage} />
</div>
)
}
}
当您在handleChange
方法中定义this
时,您明确地告诉程序查看正在编写函数的当前范围。 将它作为 prop 传递只会在其书面范围内运行该函数,而不是重新定义this
,在你的Foo
类中重新定义它也不会被证明是有帮助的。
想象一下FooClosure
和Foo
在两个不同的房间里,不知何故变成了有情众生。 FooClosure
可以制作比萨饼。 Foo
可以调用FooClosure
并要求制作比萨饼。 这里的问题是Foo
要求FooClosure
制作比萨饼,但所有原料和唯一FooClosure
烤箱都在Foo
的房间里。
在这种情况下做的最好的事情是将你的handleChange
方法到您Foo
类,所以this
可以参考Foo
和不FooClosure
这反过来又可以让你设置的状态Foo
。
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Foo extends Component {
constructor(props) {
super(props)
this.state = {
error: false
}
}
handleChange = event => {
this.setState({
error: true,
errorMessage: 'Some error happened',
})
}
render() {
const { handleChange } = this
return (
<div>
<input type='file' onChange={handleChange} id='input'/>
<label htmlFor='input'> Upload </label>
{this.state.error && <span>{this.state.errorMessage}</span>}
</div>
)
}
}
class FooClosure extends Component {
render() {
return (
<div>
<Foo />
</div>
)
}
}
class App extends Component {
render() {
return (
<div className="App">
<FooClosure />
</div>
);
}
}
export default App;
现在这当然会使您的FooClosure
类变得多余。 如果您需要根据Foo
中的 onChange 处理任何事情,您可以使用:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Foo extends Component {
constructor(props) {
super(props)
this.state = {
error: false
}
}
handleChange = event => {
const { handleFooClosureMethod } = this.props.handleFooClosureMethod
handleFooClosureMethod(args)
this.setState({
error: true,
errorMessage: 'Some error happened',
})
}
render() {
const { handleChange } = this
return (
<div>
<input type='file' onChange={handleChange} id='input'/>
<label htmlFor='input'> Upload </label>
{this.state.error && <span>{this.state.errorMessage}</span>}
</div>
)
}
}
class FooClosure extends Component {
handleChange = args => {
//handle this method
}
render() {
return (
<div>
<Foo handleFooClosureMethod={this.handleChange} />
</div>
)
}
}
class App extends Component {
render() {
return (
<div className="App">
<FooClosure />
</div>
);
}
}
export default App;
请记住,每当您的Foo
类中发生 onChange 事件时,后者都会触发。
这很有帮助,但并不完全准确。 问题在于,无论是通过绑定它还是将其建立为匿名函数,都无法将其重新绑定到 Foo 的新上下文。
class Foo extends Component {
constructor(props) {
super(props)
this.state = {
error: false
}
this.handleChange = this.props.handleChange.bind(this)
debugger
}
render() {
console.log('foo state', this.state)
return (
<div>
<input type='file' onChange={this.handleChange} id='input'/>
<label htmlFor='input'> Upload </label>
{this.state.error && <span>{this.state.errorMessage}</span>}
</div>
)
}
}
class FooClosure extends Component {
constructor(props) {
super(props)
this.handleChange = this.handleChange;
}
handleChange() {
let self = this // this will now be Foo
debugger // local this context will be Foo
this.setState({ error: true, errorMessage: 'Some error happened'})
}
render() {
console.log('closure state', this.state)
return (
<div>
<Foo handleChange={this.handleChange} />
</div>
)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.