![](/img/trans.png)
[英]Getting this.props is not function when passes function to child React
[英]Getting a typeError in React saying this.props is not a function when child component tries to call passed function
当我尝试从子功能调用传递的功能时,出现以下错误
未捕获的TypeError:this.props.addHours不是函数
这是一个带有问题的codepen: 示例
这是我的组件的代码:
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是一个。 我很确定我已经正确绑定了所有内容,这是我的第一个猜测,但也许不是。 如果有人能指出我做错了,将不胜感激!
你不使用箭头功能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>;
})}
发生这种情况,因为你正在使用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>;
})
}
在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>
...
您在这里有2个主要问题:
地图功能正在遮盖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'));
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; }
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.