Mam ten komponent:
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>
);
}
}
Chcę, aby przycisk był wyłączony, gdy wartość wejściowa jest pusta. Ale powyższy kod nie działa. To mówi:
add-item.component.js: 78 Uncaught TypeError: Cannot read property „value” of undefined
wskazuje na disabled={!this.input.value}
. Co tu robię źle? Zgaduję, że być może ref nie jest jeszcze tworzony, gdy render
metoda jest wykonywana. Jeśli tak, jakie jest obejście?
źródło
disabled
atrybut z DOM, jeśli jest ustawiony nafalse
- jest to przyjazne dla różnych przeglądarek.W HTML
Wszystkie sprowadzają się do disabled = "true", ponieważ zwraca prawdę dla niepustego ciągu. Dlatego w celu zwrócenia fałszu należy przekazać pusty ciąg w instrukcji warunkowej, takiej jak 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> ); }
źródło
Nie powinieneś ustawiać wartości wejścia za pomocą ref.
Zapoznaj się z dokumentacją dotyczącą kontrolowanych składników formularzy tutaj - https://facebook.github.io/react/docs/forms.html#controlled-components
W skrócie
<input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} />
Wtedy będziesz mógł kontrolować stan wyłączenia za pomocą
disabled={!this.state.value}
źródło
Istnieje kilka typowych metod kontrolowania renderowania komponentów w Reakcie.
Ale nie użyłem tutaj żadnego z nich, po prostu użyłem ref do przestrzeni nazw podstawowych elementów potomnych składnika.
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>
źródło
this.input
jest niezdefiniowana, dopóki nieref
zostanie wywołana funkcja zwrotna. Spróbuj ustawićthis.input
jakąś wartość początkową w konstruktorze.Z dokumentacji React na temat referencji , nacisk mój:
źródło
Miałem podobny problem, okazuje się, że nie potrzebujemy do tego hooków, możemy wykonać renderowanie warunkowe i nadal będzie działać dobrze.
<Button type="submit" disabled={ name === "" || email === "" || password === "" ? true : false } fullWidth variant="contained" color="primary" className={classes.submit}> SignUP </Button>
źródło
bardzo prostym rozwiązaniem jest użycie
useRef
hakaconst 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>
Podobnie możesz włączyć przycisk za pomocą
buttonRef.current.disabled = false
źródło
poprostu dodaj:
<button disabled={this.input.value?"true":""} className="add-item__button" onClick={this.add.bind(this)}>Add</button>
źródło