繁体   English   中英

React 中的 function scope 错误。 无法读取未定义的属性

[英]function scope error in React. Cannot read property of undefined

我是 React 和 javascript 的新手,所以请多多包涵

我正在构建一个基本的 todolist 应用程序

主要 App.js 如下

  class App extends Component {

  constructor(props) {
    super(props);
    this.fetchTasks = this.fetchTasks.bind(this)
    this.strikeUnstrike = this.strikeUnstrike.bind(this) 
  };

  state = {
    todoList: [],
    activeItem: {
      id: null,
      title: '',
      completed: false,
    },
    editing: false,
  }

  
  componentDidMount() {
    this.fetchTasks()
  }

  // pull the list of tasks from the API 
  fetchTasks() {  
    axios.get('http://127.0.0.1:8000/api/task-list/')
    .then( response => {
            this.setState({ todoList: response.data })
    } )
  } 
  
  strikeUnstrike(task) {
    task.completed = !task.completed
    let url = `http://127.0.0.1:8000/api/task-update/${task.id}/`
    let data  = {'completed': task.completed, 'title':task.title}
    axios.post( url, data)
      .then(response => this.fetchTasks() )
  }
  

  render() {
   

    return (
      <div className='container'>
        <div id ='task-container'>
          
          <TaskList
            tasks = {this.state.todoList}
            taptask = {this.strikeUnstrike(task)}
            // taptask = {() => this.strikeUnstrike(task)} // also tried this
          />    
        </div>
      </div>

    )
  }
}

export default App;

我的 TaskList.js 组件如下所示

import React from 'react';

const tasklist = (props) => {
        return (
            <div id='list-wrapper'>
                {props.tasks.map((task, index) => {
                    // console.log('the task X is :', task) // works
                    // console.log('the passed prop is :', props.taptask) //works
                return (
                    <div key={index} className="task-wrapper flex-wrapper">
                    
                    
                    <div onClick={props.taptask(task)} style={{flex:7}} >
                        
                        { task.completed == false ? (
                        <span>{task.title}</span>
                        ) : (
                        <strike>{task.title}</strike>)}
                        
                    </div>

                    <div style={{flex:1}}>
                        <button 
                        //   onClick={ props.editClick(task)} 
                        className="btn btn-sm btn-outline-info">Edit</button>
                        {console.log('working')}
                        
                    </div>

                    <div style={{flex:1}}>
                        <button 
                        //   onClick = {props.deleteClick(task)}
                        className="btn btn-sm btn-outline-dark">-</button>
                    </div>
                    </div>
                )
                })}
            </div>
        )
    
}


export default tasklist;

然而,我收到以下错误

TypeError: Cannot read property 'completed' of undefined
App.strikeUnstrike
src/frontend/src/App.js:134
  131 | // this basically allows you to check off an item as complete by clicking on it 
  132 | // strikeUnstrike = (task) => {
  133 | strikeUnstrike(task) {
> 134 |   task.completed = !task.completed
      | ^  135 |   console.log('TASK :' , task.completed)
  136 | 
  137 |   let csrfoken = this.getCookie('csrftoken')
View compiled
taptask
src/frontend/src/App.js:166
  163 | 
  164 | <TaskList
  165 |   tasks = {this.state.todoList}
> 166 |   taptask = {() => this.strikeUnstrike()}
      | ^  167 |   // taptask = {this.strikeUnstrike(task)}
  168 |   // editClick = {()=> this.startEdit(task)}
  169 |   // deleteClick = {()=> this.deleteItem(task)}
View compiled
(anonymous function)
src/frontend/src/Components/TaskList/TaskList.js:15
  12 | <div key={index} className="task-wrapper flex-wrapper">
  13 | 
  14 | 
> 15 | <div onClick={props.taptask(task)} style={{flex:7}} >
     | ^  16 |     
  17 |     { task.completed == false ? (
  18 |     <span>{task.title}</span>
View compiled

我知道绑定并且我尝试了几种方法(在构造函数中使用 this.functionName.bind(this) 和箭头 function 方法)但是我无法解决问题。 任何帮助将非常感激。

第一个选项是您事先调用 function。 第二个选项你传递一个 function ,它使用一个它不存在的task变量。

您正在将 function 传递给TaskList ,为此您应该直接传递 function ,或者将其定义为箭头 function 您应该定义task参数:

      <TaskList
        tasks = {this.state.todoList}
        taptask = {this.strikeUnstrike} // this is better
        taptask = {(task) => this.strikeUnstrike(task)} // this also works
      />  

编辑@Nadia TaskList指向您的任务列表,您还应该正确修复 onClick:

onClick={() => props.taptask(task)}

这里的问题是,您的taskundefined 所以你可以检查undefined并正确处理它,这将防止脏错误。

  133 | strikeUnstrike(task) {
> 134 |   task.completed = task && !task.completed

那么让我们找出为什么task undefined

 <TaskList
        ...
/** this will not work, because the function is executed 
immediately instead of beeing passed down as props. **/
  taptask = {this.strikeUnstrike(task)} 
//instead use this
  taptask = {this.strikeUnstrike}
//or this
  taptask = {(task) => this.strikeUnstrike(task)} // pay attention to task, which is passed down to strikeUnstrike()
      />    

请更改此行:

    taptask = {this.strikeUnstrike(task)}

对此:

    taptask = {this.strikeUnstrike}

你需要给 function 参考,你不需要调用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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