当我尝试从子函数调用传递的函数时,我收到以下错误
未捕获的TypeError:this.props.addHours不是函数
这是一个包含问题的代码:example
以下是我的组件的代码:
class Application extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.addHours = this.addHours.bind(this)
this.state = {
flies:[{
name: 'Elk Hair Caddis',
hours: 10,
fish: 12
},
{
name: 'Adams',
hours: 6,
fish: 4
}
]
};
}
handleSubmit(event) {
alert('A fly was submitted');
event.preventDefault();
let subName = document.getElementById("subName").value
let subHours = document.getElementById("subHours").value
let subFish = document.getElementById("subFish").value
document.forms[0].reset()
function flyMaker(name, hours, fish) {
this.name = name
this.hours = hours
this.fish = fish
}
let myFly = new flyMaker(subName, subHours, subFish)
let tempState = this.state.flies
tempState.push(myFly)
this.setState(tempState)
}
addHours(e){
e.preventDefault()
alert('hey')
console.log('hey')
}
render() {
return <div>
<h1>Fly List</h1>
<ul>
{this.state.flies.map(function(fly){
return <li><Fly addHours={this.addHours} name={fly.name} hours={fly.hours} fish={fly.fish} /></li>;
})}
</ul>
<div id='addFly'>
<h1>Add a Fly</h1>
<form onSubmit={this.handleSubmit}>
<p>Name:</p>
<input id='subName' type='text'/>
<p>Hours:</p>
<input id='subHours' type='text'/>
<p>Fish Caught:</p>
<input id='subFish' type='text'/>
<br/>
<input type='submit' value='submit' />
</form>
</div>
</div>;
}
}
class Fly extends React.Component {
constructor(props) {
super(props);
this.doAddHours = this.doAddHours.bind(this)
}
doAddHours() {
this.props.addHours()
}
render() {
return <div>
<p>{this.props.name}</p>
<div>Hours fished: {this.props.hours}</div>
<div className='increment' onClick={this.doAddHours}>+</div><div className='increment'>-</div>
<div>Fish Caught: {this.props.fish}</div>
<div className='increment'>+</div><div className='increment'>-</div>
</div>;
}
}
基本上,我将子组件传递给一个函数,所以我不确定为什么它不认为prop是一个。我很确定我已经把所有东西都绑定了,这是我的第一个猜测,但也许不是。如果有人能够指出我做错了什么,我将不胜感激!
答案 0 :(得分:3)
您没有在this.state.flies.map
中使用箭头功能,因此它没有获取this
的上下文所需的范围
{this.state.flies.map( fly => {
return <li><Fly addHours={this.addHours} name={fly.name} hours={fly.hours} fish={fly.fish} /></li>;
})}
答案 1 :(得分:1)
这种情况正在发生,因为您在this
内使用function() {}
。这意味着addHours
函数不在可用this
的范围内。根据您是否正在编译,您可以执行以下操作之一:
如果您愿意使用箭头功能:
{
this.state.flies.map(fly => {
return (
<li>
<Fly
addHours={this.addHours}
name={fly.name}
hours={fly.hours}
fish={fly.fish}
/>
</li>;
})
}
如果您想继续使用function() {}
:
// At the top of the render function somewhere
var _this = this;
// In your return
{
this.state.flies.map(function(fly) {
return (
<li>
<Fly
addHours={_this.addHours}
name={fly.name}
hours={fly.hours}
fish={fly.fish}
/>
</li>;
})
}
答案 2 :(得分:0)
this
内的this.state.flies.map
不是您所期望的那个。
您应该在调用map之前定义varibable以引用正确的:
render() {
const _this = this;
return <div>
<h1>Fly List</h1>
<ul>
{this.state.flies.map(function(fly){
return <li><Fly addHours={_this.addHours} name={fly.name} hours={fly.hours} fish={fly.fish} /></li>;
})}
</ul>
...
答案 3 :(得分:0)
这里有两个主要问题:
地图功能正在隐藏this
上下文。你可以提取
它是一个外部方法,并在构造函数中绑定它
或者使用箭头函数,因此它将使用词汇上下文
this
:
this.state.flies.map((fly) => {
return <li><Fly addHours={this.addHours} name={fly.name} hours={fly.hours} fish={fly.fish} /></li>;
})}
稍后您将面临的另一个问题(错误)是您不是
将事件(e
)从Fly
方法传递给父级:
doAddHours(e) {
this.props.addHours(e)
}
<小时/> 以下是代码的运行示例:
class Application extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
//this.addHours = this.addHours.bind(this)
this.state = {
flies: [{
name: 'Elk Hair Caddis',
hours: 10,
fish: 12
},
{
name: 'Adams',
hours: 6,
fish: 4
}
]
};
}
handleSubmit(event) {
//alert('A fly was submitted');
event.preventDefault();
let subName = document.getElementById("subName").value
let subHours = document.getElementById("subHours").value
let subFish = document.getElementById("subFish").value
document.forms[0].reset()
function flyMaker(name, hours, fish) {
this.name = name
this.hours = hours
this.fish = fish
}
let myFly = new flyMaker(subName, subHours, subFish)
let tempState = this.state.flies
tempState.push(myFly)
this.setState(tempState)
}
addHours = (e) => {
e.preventDefault()
//alert('hey')
console.log('hey')
}
render() {
return <div>
<h1>Fly List</h1>
<ul>
{this.state.flies.map((fly) => {
return <li><Fly addHours={this.addHours} name={fly.name} hours={fly.hours} fish={fly.fish} /></li>;
})}
</ul>
<div id='addFly'>
<h1>Add a Fly</h1>
<form onSubmit={this.handleSubmit}>
<p>Name:</p>
<input id='subName' type='text' />
<p>Hours:</p>
<input id='subHours' type='text' />
<p>Fish Caught:</p>
<input id='subFish' type='text' />
<br />
<input type='submit' value='submit' />
</form>
</div>
</div>;
}
}
class Fly extends React.Component {
constructor(props) {
super(props);
this.doAddHours = this.doAddHours.bind(this)
}
doAddHours(e) {
this.props.addHours(e)
}
render() {
return <div>
<p>{this.props.name}</p>
<div>Hours fished: {this.props.hours}</div>
<div className='increment' onClick={this.doAddHours}>+</div><div className='increment'>-</div>
<div>Fish Caught: {this.props.fish}</div>
<div className='increment'>+</div><div className='increment'>-</div>
</div>;
}
}
/*
* Render the above component into the div#app
*/
ReactDOM.render(<Application />, document.getElementById('app'));
&#13;
html, body {
height: 100%;
}
body {
background: #333;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
font-family: Helvetica Neue;
}
h1 {
font-size: 2em;
color: #eee;
display: inline-block;
}
a {
color: white;
}
p {
margin-top: 1em;
text-align: center;
color: #aaa;
}
.increment {
display: inline-block;
padding: 10px;
background-color: black;
color: white;
margin: 4px;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;