为什么在 React.js 中将函数传递给子组件时会出现未捕获的 TypeError?
Why am I getting an uncaught TypeError when I pass a function to a child component in React.js?
这是较大代码库的一小部分。但我相信这是这个问题唯一需要的相关部分。
我有两个组件 DataSeries
和 Sector
。 DataSeries
组件由另一个父组件渲染。 Sector
组件由 DataSeries
组件渲染。我将函数作为 属性 从 DataSeries
传递到 Sector
。但是,当我尝试从 Sector
调用该函数时,出现 Uncaught TypeError: this.props.someFunc is not a function
错误。我不太确定为什么。有什么帮助吗?
这是代码。
var Sector = React.createClass({
getInitialState: function() {
return {text: '', count:'', opacity:'arc'};
},
formatNumber: function(num, digits) {
//irrelevant function
return num;
},
render: function() {
var outerRadius = this.props.width/2.2;
var innerRadius = this.props.width/3.5;
var arc = d3.svg.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
var data = this.props.data;
var center = "translate(" + arc.centroid(data) + ")";
var nameCenter = "translate(0,0)";
var countCenter = "translate(0,50)"
var color = this.props.colors;
var formattedCount = this.formatNumber(this.state.count, 1)
return (
<g onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} onClick={this.onClick}>
<path className={this.state.opacity} fill={color[this.props.ikey]} d={arc(this.props.data)}></path>
<text fill={color[this.props.ikey]} stroke={color} fontSize="27px" transform={nameCenter} textAnchor="middle">{this.state.text}</text>
<text fill={"#868686"} stroke={color} fontSize="25px" transform={countCenter} textAnchor="middle">{formattedCount}</text>
</g>
);
},
onMouseOver: function() {
this.setState({text: '', count:'', opacity:'arc-hover'});
this.setState({text: this.props.name, count:this.props.data.value});
console.log("Inside onMouseOver")
this.props.someFunc();
},
onMouseOut: function() {
this.setState({text: '', count: '', opacity:'arc'});
},
onClick: function() {
//Do something on click?
}
});
var DataSeries = React.createClass({
propTypes: {
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired,
color: React.PropTypes.array,
data: React.PropTypes.array.isRequired,
},
randomFunction: function() {
console.log("Random Function")
},
render: function() {
var color = this.props.colors;
var data = this.props.data;
var width = this.props.width;
var height = this.props.height;
var pie = d3.layout.pie();
var result = data.map(function(item){
return item.count;
})
console.log(result)
var names = data.map(function(item){
return item.name;
})
var sum = result.reduce(function(memo, num){ return memo + num; }, 0);
var position = "translate(" + (width)/2 + "," + (height)/2 + ")";
var arcs = (pie(result)).map(function(point, i) {
return (
<Sector
data={point}
ikey={i}
key={i}
name={names[i]}
colors={color}
total={sum}
width={width}
height={height}
someFunc={this.randomFunction}/>
)
});
return (
<g transform={position}>
{arcs}
</g>
);
}
});
当您使用 map
时,this
表示的上下文发生变化。因此,目前,在您的 map
调用中,this.randomFunction
实际上是 "undefined"
。
因此,要使用其中包含您的函数的 Sector
的 this
上下文,您需要将 Sector
的 this
绑定到 map
的匿名函数。
var arcs = (pie(result)).map(function(point, i) {
return (
<Sector
data={point}
ikey={i}
key={i}
name={names[i]}
colors={color}
total={sum}
width={width}
height={height}
someFunc={this.randomFunction}
/>
)
}.bind(this));
这样做是将匿名函数内部 this
的上下文设置为来自 Sector
.
的 this
这是较大代码库的一小部分。但我相信这是这个问题唯一需要的相关部分。
我有两个组件 DataSeries
和 Sector
。 DataSeries
组件由另一个父组件渲染。 Sector
组件由 DataSeries
组件渲染。我将函数作为 属性 从 DataSeries
传递到 Sector
。但是,当我尝试从 Sector
调用该函数时,出现 Uncaught TypeError: this.props.someFunc is not a function
错误。我不太确定为什么。有什么帮助吗?
这是代码。
var Sector = React.createClass({
getInitialState: function() {
return {text: '', count:'', opacity:'arc'};
},
formatNumber: function(num, digits) {
//irrelevant function
return num;
},
render: function() {
var outerRadius = this.props.width/2.2;
var innerRadius = this.props.width/3.5;
var arc = d3.svg.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
var data = this.props.data;
var center = "translate(" + arc.centroid(data) + ")";
var nameCenter = "translate(0,0)";
var countCenter = "translate(0,50)"
var color = this.props.colors;
var formattedCount = this.formatNumber(this.state.count, 1)
return (
<g onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} onClick={this.onClick}>
<path className={this.state.opacity} fill={color[this.props.ikey]} d={arc(this.props.data)}></path>
<text fill={color[this.props.ikey]} stroke={color} fontSize="27px" transform={nameCenter} textAnchor="middle">{this.state.text}</text>
<text fill={"#868686"} stroke={color} fontSize="25px" transform={countCenter} textAnchor="middle">{formattedCount}</text>
</g>
);
},
onMouseOver: function() {
this.setState({text: '', count:'', opacity:'arc-hover'});
this.setState({text: this.props.name, count:this.props.data.value});
console.log("Inside onMouseOver")
this.props.someFunc();
},
onMouseOut: function() {
this.setState({text: '', count: '', opacity:'arc'});
},
onClick: function() {
//Do something on click?
}
});
var DataSeries = React.createClass({
propTypes: {
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired,
color: React.PropTypes.array,
data: React.PropTypes.array.isRequired,
},
randomFunction: function() {
console.log("Random Function")
},
render: function() {
var color = this.props.colors;
var data = this.props.data;
var width = this.props.width;
var height = this.props.height;
var pie = d3.layout.pie();
var result = data.map(function(item){
return item.count;
})
console.log(result)
var names = data.map(function(item){
return item.name;
})
var sum = result.reduce(function(memo, num){ return memo + num; }, 0);
var position = "translate(" + (width)/2 + "," + (height)/2 + ")";
var arcs = (pie(result)).map(function(point, i) {
return (
<Sector
data={point}
ikey={i}
key={i}
name={names[i]}
colors={color}
total={sum}
width={width}
height={height}
someFunc={this.randomFunction}/>
)
});
return (
<g transform={position}>
{arcs}
</g>
);
}
});
当您使用 map
时,this
表示的上下文发生变化。因此,目前,在您的 map
调用中,this.randomFunction
实际上是 "undefined"
。
因此,要使用其中包含您的函数的 Sector
的 this
上下文,您需要将 Sector
的 this
绑定到 map
的匿名函数。
var arcs = (pie(result)).map(function(point, i) {
return (
<Sector
data={point}
ikey={i}
key={i}
name={names[i]}
colors={color}
total={sum}
width={width}
height={height}
someFunc={this.randomFunction}
/>
)
}.bind(this));
这样做是将匿名函数内部 this
的上下文设置为来自 Sector
.
this