简体   繁体   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

When I try to call the passed function from the child function, I get the following error 当我尝试从子功能调用传递的功能时,出现以下错误

Uncaught TypeError: this.props.addHours is not a function 未捕获的TypeError:this.props.addHours不是函数

Here's a codepen with the issue: example 这是一个带有问题的codepen: 示例

Here's the code with my components: 这是我的组件的代码:

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>;
  }
}

Basically, I'm passing the child component a function so I'm not sure why it doesn't think the prop is one. 基本上,我给子组件传递了一个函数,所以我不确定为什么它不认为prop是一个。 I'm pretty sure I've bond everything correctly, which was my first guess, but perhaps not. 我很确定我已经正确绑定了所有内容,这是我的第一个猜测,但也许不是。 It would be greatly appreciated if someone could point out what I'm doing wrong! 如果有人能指出我做错了,将不胜感激!

you do not use an arrow function in this.state.flies.map so it does not have the scope needed to get the context for this 你不使用箭头功能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 is happening because you are using this inside a function() {} . 发生这种情况,因为你正在使用this一个内部function() {} which means the addHours function is not in scope for the available this . 这意味着addHours函数不在可用this范围内。 Depending on if you are compiling this or not you can do one of the following: 根据您是否进行编译,可以执行以下操作之一:

If you are open to using an arrow function: 如果您愿意使用箭头功能:

{
  this.state.flies.map(fly => {
    return (
      <li>
        <Fly
          addHours={this.addHours}
          name={fly.name}
          hours={fly.hours}
          fish={fly.fish}
        />
      </li>;
  })
}

if you want to continue using function() {} : 如果您想继续使用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>;
  })
}

The this inside your this.state.flies.map is not the one you are expected. this里面你this.state.flies.map是不是你所期望的一个。 You should defined varibable before calling map to reference the correct this: 您应在调用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>
...

You have 2 main issues here: 您在这里有2个主要问题:

  1. The map function is shadowing the this context. 地图功能正在遮盖this上下文。 You can extract it to an external method and bind it as well in the constructor 您可以将其提取到外部方法,并在构造函数中将其绑定
    Or use an arrow function so it will use a lexical context for the this : 或使用箭头函数,以便this使用词法上下文:

     this.state.flies.map((fly) => { return <li><Fly addHours={this.addHours} name={fly.name} hours={fly.hours} fish={fly.fish} /></li>; })} 
  2. Another issue (error) you will face later is that you are not passing the event ( e ) from the Fly method to the parent: 您稍后将面临的另一个问题(错误)是您没有将事件( e )从Fly方法传递给父方法:

      doAddHours(e) { this.props.addHours(e) } 


    Here is a running example of your code: 这是代码的运行示例:

 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.

相关问题 将函数传递给子React时获取this.props不起作用 - Getting this.props is not function when passes function to child React this.props不是从父组件到子组件的函数还原 - this.props is not a function redux from parent to child component React:将函数作为道具传递给子组件,在子组件中调用onClick - React: Pass function to child component as props, call onClick in child component this.props在React Component中的箭头函数中显示为undefined - this.props shows as undefined in an arrow function within React Component 传递了一个 function 作为道具,但它没有在 React 的子组件中执行 - Passed a function as props but it's not executing in child component in React TypeError: this.props is not a function on handleCHange 事件 - TypeError: this.props is not a function on handleCHange event 2个具有地图功能的道具传递给子组件 - 2 Props passed to Child Component with a Map Function 获取TypeError:_red2.props.handleClick不是一个函数,当将redux prop从容器传递到react中的表示组件时 - Getting TypeError: _this2.props.handleClick is not a function when passing redux prop from container to presentational component in react 如何测试 function 在 React 中作为道具传递给孩子? - How to test a function passed as props to child in React? 在react ComponentDidMount中访问this.props函数 - Accessing this.props function in react ComponentDidMount
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM