繁体   English   中英

当子组件尝试调用传递的函数时,在React中获取typeError提示this.props不是函数

[英]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个主要问题:

  1. 地图功能正在遮盖this上下文。 您可以将其提取到外部方法,并在构造函数中将其绑定
    或使用箭头函数,以便this使用词法上下文:

     this.state.flies.map((fly) => { return <li><Fly addHours={this.addHours} name={fly.name} hours={fly.hours} fish={fly.fish} /></li>; })} 
  2. 您稍后将面临的另一个问题(错误)是您没有将事件( 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM