React - uncaught TypeError: Невозможно прочитать свойство 'setState' из неопределенного
Я получаю следующую ошибку
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>
);
}
}
Ответы
Ответ 1
Это связано с тем, что 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 возвращает связанную функцию. Вам нужно установить функцию на ее значение привязки.
Ответ 2
В ES7 + (ES2016) вы можете использовать экспериментальный оператор привязки функции для привязки ::
. Это синтаксический сахар и будет делать то же самое, что и ответ Дэвина Триона.
Затем вы можете переписать this.delta = this.delta.bind(this);
на this.delta = ::this.delta;
Для ES6 + (ES2015) вы также можете использовать функцию со стрелкой ES6 + (=>
) использовать this
.
delta = () => {
this.setState({
count : this.state.count + 1
});
}
Почему? Из документа Mozilla:
Пока функции стрелок, каждая новая функция определяет свое значение [...]. Это оказалось раздражающим объектно-ориентированным стилем программирования.
Функции стрелок фиксируют это значение окружающего контекста [...]
Ответ 3
Существует различие между 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>
Ответ 4
При использовании кода ES6 в React всегда используйте функции стрелок, потому что контекст this автоматически привязывается к нему
Используйте это:
(videos) => {
this.setState({ videos: videos });
console.log(this.state.videos);
};
вместо
function(videos) {
this.setState({ videos: videos });
console.log(this.state.videos);
};
Ответ 5
Вам не нужно ничего связывать, просто используйте функции Arrow следующим образом:
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>
);
}
}
Ответ 6
Вы также можете использовать:
<button onClick={()=>this.delta()}>+</button>
Или же:
<button onClick={event=>this.delta(event)}>+</button>
Если вы передаете некоторые параметры..
Ответ 7
Вам нужно связать это с конструктором и помнить, что изменения в конструкторе требуют перезапуска сервера. Или иначе, вы закончите с той же ошибкой.
Ответ 8
Вы должны связать свои методы с этим (объект по умолчанию). Так что, какой бы ни была ваша функция, просто свяжите это в конструкторе.
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>
);
Ответ 9
Вы должны связать новое событие с этим ключевым словом, как я упоминаю ниже...
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta = 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
Добавление
OnClick = {this.delta.bind (это)}
решит проблему. эта ошибка возникает, когда мы пытаемся вызвать функцию класса ES6, поэтому нам нужно связать метод.
Ответ 11
Эта ошибка может быть устранена различными methods-
-
Если вы используете синтаксис ES5, то в соответствии с документацией React JS вы должны использовать метод связывания.
Примерно так в приведенном выше примере:
this.delta = this.delta.bind(this)
-
Если вы используете синтаксис ES6, вам не нужно использовать метод bind, вы можете сделать это примерно так:
delta=()=>{ this.setState({ count: this.state.count++ }); }
Ответ 12
хотя этот вопрос уже имел решение, я просто хочу поделиться своим, чтобы он был очищен, надеюсь, что он может помочь:
/*
* The root cause is method doesn't in the App context
* so that it can't access other attributes of "this".
* Below are few ways to define App 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() {
//....
}
}
Ответ 13
<!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>
Ответ 14
Просто измените свое выражение на связывание с того, что вы должны => this.delta = this.delta.bind(this);
Ответ 15
- Проверьте состояние, проверьте состояние, создаете ли вы конкретное свойство или нет
this.state = {
name: "",
email: ""
}
this.setState(() => ({
comments: comments //comments not available in state
}))