Cách tắt nút trong React.js


84

Tôi có thành phần này:

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 nút bị vô hiệu hóa khi giá trị đầu vào trống. Nhưng đoạn mã trên không hoạt động. Nó nói rằng:

add-item.component.js: 78 Uncaught TypeError: Không thể đọc thuộc tính 'value' của undefined

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

Câu trả lời:


109

Sử dụng refs không phải là phương pháp hay nhất vì nó đọc DOM trực tiếp, tốt hơn nên sử dụng React's 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 setStatecùng với trình onChangenghe sự kiện để hiển thị lại thành phần mỗi khi trường đầu vào thay đổi:

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

Đây là một ví dụ hoạt động:

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>


Đây là câu trả lời chính xác! Trạng thái bên trong nên được sử dụng để cập nhật về sự thay đổi của đầu vào và nút chỉ nên kiểm tra điều này. +1
Michael Giovanni Pumo

this.state có một hạn chế là nó hiển thị lại giao diện người dùng, vì vậy nếu bạn đang nhập vào một hộp văn bản trong một thành phần con và đã liên kết với sự kiện onChange, nó sẽ mất tiêu điểm khỏi hộp văn bản. Nếu nó trong cùng một thành phần thì không sao nhưng khi được sử dụng trong một thành phần con, nó sẽ mất tập trung.
Động

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

Chỉ FYI, điều này không thân thiện với nhiều trình duyệt. Nhiều trình duyệt vẫn giải thích sự hiện diện của bị vô hiệu hóa là đúng ngay cả khi được đặt thành sai. Giống như nó theo nghĩa đen chỉ kiểm tra sự hiện diện của thuộc tính bị vô hiệu hóa. Bạn phải xóa thuộc tính đã tắt để thân thiện với nhiều trình duyệt.
Adrianopolis

@Adrianopolis React xóa disabledthuộc tính khỏi DOM nếu nó được đặt thành false—đây là thuộc tính thân thiện với nhiều trình duyệt.
Fabian Schultz

9

Trong HTML,

<button disabled/>
<buttton disabled="true">
<buttton disabled="false">
<buttton disabled="21">

Tất cả chúng đều tổng hợp thành disable = "true" vì nó trả về true cho một chuỗi không rỗng. Do đó, để trả về false, hãy chuyển một chuỗi trống trong một câu lệnh điều kiện như this.input.value? "True": "" .

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?"true":""} className="add-item__button" onClick={this.add.bind(this)}>Add</button>
        </div>
    );
}

nếu stack-tràn có tùy chọn câu trả lời hỗ trợ, tôi sẽ chọn câu trả lời này
Feras

6

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

Hãy xem tài liệu về các thành phần biểu mẫu được kiểm soát tại đâ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 trạng thái bị vô hiệu hóa bằng cách sử dụng disabled={!this.state.value}


4

Có một vài 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 React. nhập mô tả hình ảnh ở đây

Nhưng, tôi chưa sử dụng bất kỳ cái nào trong số này ở đây, tôi chỉ sử dụng các tham chiếu cho không gian tên con cơ bản của 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>


2

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

Từ tài liệu React về refs , tôi nhấn mạnh:

lệnh gọi lại sẽ được thực thi ngay lập tức sau khi thành phần được gắn kết hoặc tháo gỡ


0

Tôi đã gặp vấn đề tương tự, hóa ra chúng ta không cần hook để làm những điều này, chúng ta có thể thực hiện kết xuất có điều kiện và nó vẫn hoạt động tốt.

<Button
    type="submit"
    disabled={
        name === "" || email === "" || password === "" ? true : false
    }
    fullWidth
    variant="contained"
    color="primary"
    className={classes.submit}>
    SignUP
</Button>

0

chỉ cần thêm:

<button disabled={this.input.value?"true":""} className="add-item__button" onClick={this.add.bind(this)}>Add</button>

0

giải pháp rất đơn giản cho việc này là sử dụng useRefhook

const buttonRef = useRef();

const disableButton = () =>{
  buttonRef.current.disabled = true; // this disables the button
 }

<button
className="btn btn-primary mt-2"
ref={buttonRef}
onClick={disableButton}
>
    Add
</button>

Tương tự, bạn có thể bật nút bằng cách sử dụng buttonRef.current.disabled = false

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.