React-uncaught TypeError: не удается прочитать свойство 'setState' из undefined
Я получаю следующую ошибку
Uncaught TypeError: не удается прочитать свойство 'setState' из undefined
даже после привязки Дельта в конструкторе.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
10 ответов:
это связано с
this.deltaне обязанthis.для того, чтобы привязать set
this.delta = this.delta.bind(this)в конструкторе:constructor(props) { super(props); this.state = { count : 1 }; this.delta = this.delta.bind(this); }В настоящее время вы вызываете bind. Но bind возвращает связанную функцию. Вам нужно установить функцию в ее связанное значение.
на ES7+ (ES2016) вы можете использовать экспериментальный функции bind синтаксис оператор
::для персонализация. Это синтаксический сахар и будет делать то же самое, что и ответ Дэвина Триона.затем вы можете переписать
this.delta = this.delta.bind(this);доthis.delta = ::this.delta;
на ES6+ (ES2015) вы также можете использовать ES6+ функции стрелочку (
=>), чтобы иметь возможность использоватьthis.delta = () => { this.setState({ count : this.state.count + 1 }); }почему ? Из документа Mozilla :
до стрелочных функций каждая новая функция определяла свою собственную этой значение [...]. Это оказалось раздражающим с объектно-ориентированным стилем программирования.
стрелки функции захвата этой значение окружающего контекста [...]
существует разница контекста между классами ES5 и ES6. Таким образом, между реализациями также будет небольшая разница.
вот версия ES5:
var Counter = React.createClass({ getInitialState: function() { return { count : 1 }; }, delta: function() { this.setState({ count : this.state.count++ }); }, render: function() { return ( <div> <h1>{this.state.count}</h1> <button onClick={this.delta}>+</button> </div> ); } });и вот версия ES6:
class Counter extends React.Component { constructor(props) { super(props); this.state = { count : 1 }; } delta() { this.setState({ count : this.state.count++ }); } render() { return ( <div> <h1>{this.state.count}</h1> <button onClick={this.delta.bind(this)}>+</button> </div> ); } }просто будьте осторожны, кроме разницы синтаксиса в реализации класса, есть разница в привязке обработчика событий.
в версии ES5, это
<button onClick={this.delta}>+</button>в версии ES6 , это:
<button onClick={this.delta.bind(this)}>+</button>
при использовании кода ES6 в React всегда используйте функции стрелки, потому что этой контекст автоматически связывается с ним
используйте этот:
(videos) => { this.setState({ videos: videos }); console.log(this.state.videos); };вместо:
function(videos) { this.setState({ videos: videos }); console.log(this.state.videos); };
вам нужно привязать это к конструктору и помнить, что изменения в конструкторе требуют перезагрузки сервера. Или же вы закончите с той же ошибкой.
вы должны связать свои методы с 'this' (объект по умолчанию). Поэтому какая бы ни была ваша функция, просто свяжите ее в конструкторе.
constructor(props) { super(props); this.state = { checked:false }; this.handleChecked = this.handleChecked.bind(this); } handleChecked(){ this.setState({ checked: !(this.state.checked) }) } render(){ var msg; if(this.state.checked){ msg = 'checked' } else{ msg = 'not checked' } return ( <div> <input type='checkbox' defaultChecked = {this.state.checked} onChange = {this.handleChecked} /> <h3>This is {msg}</h3> </div> );
вам не нужно ничего связывать, просто используйте функции стрелки, как это:
class Counter extends React.Component { constructor(props) { super(props); this.state = { count : 1 }; } //ARROW FUNCTION delta = () => { this.setState({ count : this.state.count++ }); } render() { return ( <div> <h1>{this.state.count}</h1> <button onClick={this.delta}>+</button> </div> ); }}
вы также можете использовать:
<button onClick={()=>this.delta()}>+</button>или:
<button onClick={event=>this.delta(event)}>+</button>Если вы передаете некоторые параметры..
хотя этот вопрос уже имел решение, я просто хочу поделиться своим, чтобы он был очищен, надеюсь, что это может помочь:
/* * The root cause is method doesn't in the App's context * so that it can't access other attributes of "this". * Below are few ways to define App's method property */ class App extends React.Component { constructor() { this.sayHi = 'hello'; // create method inside constructor, context = this this.method = ()=> { console.log(this.sayHi) }; // bind method1 in constructor into context 'this' this.method1 = this.method.bind(this) } // method1 was defined here method1() { console.log(this.sayHi); } // create method property by arrow function. I recommend this. method2 = () => { console.log(this.sayHi); } render() { //.... } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello World</title> <script src="https://unpkg.com/[email protected]/dist/react.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script> <script src="https://unpkg.com/[email protected]/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> class App extends React.Component{ constructor(props){ super(props); this.state = { counter : 0, isToggle: false } this.onEventHandler = this.onEventHandler.bind(this); } increment = ()=>{ this.setState({counter:this.state.counter + 1}); } decrement= ()=>{ if(this.state.counter > 0 ){ this.setState({counter:this.state.counter - 1}); }else{ this.setState({counter:0}); } } // Either do it as onEventHandler = () => {} with binding with this // object. onEventHandler(){ this.setState({isToggle:!this.state.isToggle}) alert('Hello'); } render(){ return( <div> <button onClick={this.increment}> Increment </button> <button onClick={this.decrement}> Decrement </button> {this.state.counter} <button onClick={this.onEventHandler}> {this.state.isToggle ? 'Hi':'Ajay'} </button> </div> ) } } ReactDOM.render( <App/>, document.getElementById('root'), ); </script> </body> </html>
Comments