我正在尝试为应用添加一些过滤但我的更改处理程序似乎没有引用'this'?知道我在这里做错了吗?
class ShipmentList extends Component {
constructor(props) {
super(props)
this.state = {
shipments: [],
searchString: '',
loading: false
}
}
handleChange(e){
this.setState( {searchString:e.target.value} ) // <- This is where the error happens
}
componentDidMount() {
this.setState({loading: true})
fetch('/shipments-server.json')
.then(response => response.json())
.then(shipments => this.setState({
shipments,
loading: false
}))
render() {
const { shipments, loading, searchString } = this.state
var shipmentData = shipments
var filter = this.state.searchString
if( filter.length > 0 ) {
shipmentData = shipmentData.filter(s => {
return s.carrierName.toLowerCase().match( filter.trim().toLowerCase() )
});
}
return (
<div className="shipment-list">
<ul className="filters">
<li><input value={this.state.searchString} onChange={this.handleChange} placeholder="Filter by Carrier" type="text" /></li>
我的数据从JSON文件加载得很好,但是当我输入到输入文本框并且调用了handleChange()方法时,我看到错误'无法获取属性'setState'为undefined或null reference'。当我在编译代码中设置断点时,我可以看到在handleChange()方法的范围内未定义'this',但我不明白为什么。任何帮助将不胜感激。
答案 0 :(得分:3)
使用较新的ES6类语法时,您将失去createClass
提供的自动绑定功能。这是一个刻意的改变,因为JavaScript类也没有进行自动绑定(所以行为是一致的),你可以在这里阅读更多相关内容:https://facebook.github.io/react/docs/react-without-es6.html#autobinding
要解决此问题,您可以返回旧的createClass
语法,也可以通过以下两种方式手动将上下文绑定到您的方法:
bind()
:<input onChange={this.handleChange.bind(this)} />
<input onChange={() => this.handleChange()} />
<input onChange={::this.handleChange} />
这个的一个小问题是bind()
和箭头函数声明(可能也是绑定运算符,但不是100%肯定)基本上会创建一个新方法,每次render()
函数被调用。这有一些性能影响(尽管您通常不必担心这一点)。但是,如果这是一个问题,您可以考虑在初始化时将有界方法分配给变量并参考该变量。像这样:
constructor(props) {
// ...
this.handleChange = this.handleChange.bind(this);
}
或者,如果您的Babel配置允许使用Class Properties语法,您甚至可以跳过必须编写类似这些的分配(并且必须在需要时找出它们),只需直接使用箭头函数即可:
class ShipmentList extends Component {
handleChange = () => {
// your handleChange code
}
}
答案 1 :(得分:2)
您需要绑定this
。在构造函数中尝试这个:
constructor(props) {
super(props)
this.state = {
shipments: [],
searchString: '',
loading: false
}
this.handleChange = this.handleChange.bind(this);
}
答案 2 :(得分:2)
你缺少绑定handleChange
试试这样:
<input value={this.state.searchString} onChange={this.handleChange.bind(this)} placeholder="Filter by Carrier" type="text" />
就像@fabian-schultz指出的那样,如果你担心性能的下降,你也可以在构造函数中做到这一点:
constructor(props) {
super(props)
this.state = {
shipments: [],
searchString: '',
loading: false
}
this.handleChange = this.handleChange.bind(this);
}