2017-01-05 79 views
8

tôi có thành phần này:Làm thế nào để vô hiệu hóa nút trong React.js

import React from 'react'; 

export default class AddItem extends React.Component { 

add() { 
    this.props.onButtonClick(this.input.value); 
    this.input.value = ''; 
} 


render() { 
    return (
     <div className="add-item"> 
      <input type="text" className="add-item__input" ref={(input) => this.input = input} placeholder={this.props.placeholder} /> 
      <button disabled={!this.input.value} className="add-item__button" onClick={this.add.bind(this)}>Add</button> 
     </div> 
    ); 
} 

} 

Tôi muốn các nút bị vô hiệu khi giá trị đầu vào là rỗng. Nhưng đoạn mã trên không hoạt động. Nó nói:

add-item.component.js:78 Uncaught TypeError: Cannot read property 'value' of undefined

trỏ đến disabled={!this.input.value}. Tôi có thể làm gì sai ở đây? Tôi đoán rằng có lẽ ref chưa được tạo ra khi phương thức render được thực thi. Nếu, do đó, workararound là gì?

Trả lời

18

Sử dụng refs là thực tế không tốt nhất bởi vì nó đọc DOM trực tiếp, nó tốt hơn để sử dụng Phản ứng của state để thay thế. Ngoài ra, nút của bạn không thay đổi vì thành phần không được hiển thị lại và vẫn ở trạng thái ban đầu.

Bạn có thể sử dụng setState cùng với một người biết lắng nghe onChange sự kiện để làm cho thành phần một lần nữa mỗi khi thay đổi lĩnh vực đầu vào:

// Input field listens to change, updates React's state and re-renders the component. 
<input onChange={e => this.setState({ value: e.target.value })} value={this.state.value} /> 

// Button is disabled when input state is empty. 
<button disabled={!this.state.value} /> 

Dưới đây là một ví dụ làm việc:

class AddItem extends React.Component { 
 
    constructor() { 
 
    super(); 
 
    this.state = { value: '' }; 
 
    this.onChange = this.onChange.bind(this); 
 
    this.add = this.add.bind(this); 
 
    } 
 

 
    add() { 
 
    this.props.onButtonClick(this.state.value); 
 
    this.setState({ value: '' }); 
 
    } 
 

 
    onChange(e) { 
 
    this.setState({ value: e.target.value }); 
 
    } 
 

 
    render() { 
 
    return (
 
     <div className="add-item"> 
 
     <input 
 
      type="text" 
 
      className="add-item__input" 
 
      value={this.state.value} 
 
      onChange={this.onChange} 
 
      placeholder={this.props.placeholder} 
 
     /> 
 
     <button 
 
      disabled={!this.state.value} 
 
      className="add-item__button" 
 
      onClick={this.add} 
 
     > 
 
      Add 
 
     </button> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(
 
    <AddItem placeholder="Value" onButtonClick={v => console.log(v)} />, 
 
    document.getElementById('View') 
 
);
<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='View'></div>

+0

Đây là câu trả lời đúng! Trạng thái nội bộ nên được sử dụng để cập nhật thay đổi đầu vào và nút đơn giản nên kiểm tra điều này. +1 –

+0

this.state có giới hạn là nó hiển thị lại giao diện người dùng vì vậy nếu bạn nhập vào một hộp văn bản trong thành phần con và đã ràng buộc với sự kiện onChange, nó sẽ mất tiêu điểm từ hộp văn bản. Nếu nó trong cùng một thành phần thì tốt nhưng khi được sử dụng trong một thành phần con nó sẽ mất tiêu điểm. – Dynamic

+0

@Dynamic Điều đó không nên xảy ra. Bạn có một ví dụ làm việc về điều đó? –

2

Bạn không nên đặt giá trị của đầu vào thông qua các lần thay đổi.

Hãy xem tài liệu cho các thành phần hình thức kiểm soát ở đây - https://facebook.github.io/react/docs/forms.html#controlled-components

Tóm lại

<input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} /> 

Sau đó, bạn sẽ có thể kiểm soát tình trạng khuyết tật bằng cách sử dụng disabled={!this.state.value}

1

this.input là không xác định cho đến khi gọi lại ref. Hãy thử đặt this.input thành một số giá trị ban đầu trong hàm tạo của bạn.

Từ the React docs on refs, tôi nhấn mạnh:

the callback will be executed immediately after the component is mounted or unmounted

0

Có một số phương pháp điển hình cách chúng tôi kiểm soát các thành phần hiển thị trong Phản ứng. enter image description here

Nhưng, tôi chưa từng sử dụng bất kỳ thứ gì trong số này ở đây, tôi chỉ sử dụng ref để không gian tên cơ bản cho trẻ em thành phần.

class AddItem extends React.Component { 
 
    change(e) { 
 
     if ("" != e.target.value) { 
 
     this.button.disabled = false; 
 
     } else { 
 
     this.button.disabled = true; 
 
     } 
 
    } 
 

 
    add(e) { 
 
     console.log(this.input.value); 
 
     this.input.value = ''; 
 
     this.button.disabled = true; 
 
    } 
 

 
    render() { 
 
     return (
 
      <div className="add-item"> 
 
      <input type="text" className = "add-item__input" ref = {(input) => this.input=input} onChange = {this.change.bind(this)} /> 
 
      
 
      <button className="add-item__button" 
 
      onClick= {this.add.bind(this)} 
 
      ref={(button) => this.button=button}>Add 
 
      </button> 
 
      </div> 
 
     ); 
 
    } 
 
} 
 

 
ReactDOM.render(<AddItem/> , document.getElementById('root'));
<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="root"></div>

Các vấn đề liên quan