2016-08-27 31 views
7

Tôi đang tạo ra ứng dụng phản ứng rất đơn giản. Tuy nhiên, khi tôi cố gắng gọi phương thức của thành phần cha mẹ (thực sự là ông bà) thông qua sự kiện onChange, tôi tiếp tục nhận được Uncaught TypeError: Cannot read property 'props' of undefined. Đây là thành phần/biểu mẫu đang kích hoạt sự kiện (do đó gọi phương thức trên thành phần cha mẹ được ràng buộc ... Có, tôi đã sử dụng .bound (this) trên phương thức khi tôi truyền nó xuống từ thành phần cha thông qua các đạo cụ.).React.js - Không thể đọc thuộc tính không xác định

class MonthsTable extends Component { 
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); // here the method is not found, causing error. 
    } 
    render(){ 
    console.log(this.props.setMonth) // here the method is present alright 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} // yes I know, bad habit, but in this case it doesn't matter 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth} />)} 
    </form>) 
    } 
} 

Đây là cách tôi chuyển phương thức làm đạo cụ từ phần lớn phụ huynh (ông bà).

<Months setMonth={this.setMonth.bind(this)} /> 

Sau đây là cách tôi vượt qua các phương pháp như đạo cụ trong các phụ huynh (các thành phần đó là giữa chủ sở hữu phương pháp và phương pháp Invoker)

<MonthsTable setMonth={this.props.setMonth} /> 

Và cuối cùng thông qua với thành phần (MonthsTable) mà bạn nhìn thấy đầu tiên . Wheter nó là có liên quan hay không, cuối cùng (hầu hết trẻ em) thành phần được hiển thị tùy thuộc vào nếu tuyên bố mà hoạt động tốt (Có thể bằng cách nào đó có liên quan, tôi không biết).

Câu hỏi là ... Tại sao phương thức (setMonth) 'ẩn' bên trong phương thức (handleChangeOnMonth).

Cảm ơn lời khuyên nào.

+0

Thử ràng buộc 'this.handleChangeOnMonth' sang' this' nữa? –

Trả lời

5

Vấn đề thực tế ở đây là ngữ cảnh this không được xác định trong hàm handleChangeOnMonth của bạn. Điều này là do javascript xử lý ngữ cảnh của các hàm, về cơ bản khi gọi các hàm nếu bạn không gọi chúng trực tiếp từ đối tượng, và chúng không bị ràng buộc chúng sẽ không có ngữ cảnh xác định, và vì bạn đang chuyển hàm như một tham số cho thành phần đầu vào, nó mất bối cảnh.

Cách đơn giản nhất để khắc phục điều này là để ràng buộc chức năng, tôi đề nghị bạn nên liên kết các chức năng trong các nhà xây dựng, như vậy:

class MonthsTable extends Component { 
    constructor(props, context){ 
    super(props, context); 
    this.handleChangeOnMonth = this.handleChangeOnMonth.bind(this); 
    } 
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); 
    } 
    render(){ 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth} />)} 
    </form>) 
    } 
} 

cách khác nếu bạn đang sử dụng trang trí, bạn có thể sử dụng gói core-decorators để làm điều này một cách thanh lịch hơn:

import {autobind} from "core-decorators" 

@autobind 
class MonthsTable extends Component {  
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); 
    } 
    render(){ 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth} />)} 
    </form>) 
    } 
} 
0

Bạn phải ràng buộc chức năng được cung cấp cho onChange với ngữ cảnh hiện tại. Bạn có thể liên kết nó với hàm tạo của lớp hoặc bạn có thể liên kết nó trực tiếp với onChange(), đây là một thực hành không tốt.

class MonthsTable extends Component { 
    constructor(props){ 
    super(props); 
    this.handleChangeOnMonth = this.handleChangeOnMonth.bind(this); 
    } 
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); // here the method is not found, causing error. 
    } 
    render(){ 
    console.log(this.props.setMonth) // here the method is present alright 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} // yes I know, bad habit, but in this case it doesn't matter 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth.bind(this)} />)} 
    </form>) 
    } 
} 
Các vấn đề liên quan