以下のエラーが出ます
捕捉されないTypeError:未定義のプロパティ 'setState'を読み込めません
コンストラクタでdeltaをバインドした後でも。
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>
);
}
}
これは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)では、実験的な 関数バインド構文 operator ::
を使用してバインドできます。これは構文上の糖であり、Davin Tryonの答えと同じことをします。
this.delta = this.delta.bind(this);
をthis.delta = ::this.delta;
に書き換えることができます。
ES6 + (ES2015)の場合は、ES6 + 矢印関数 (=>
)を使用してthis
を使用できます。
delta = () => {
this.setState({
count : this.state.count + 1
});
}
どうして ? Mozillaのドキュメントから:
矢印関数まで、新しい関数はそれぞれ独自のthis value [...]を定義していました。これはオブジェクト指向のプログラミングスタイルでは厄介なことになりました。
矢印関数は、囲んでいるコンテキストのthisの値をとらえます[...]
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で使用するときは常に矢印関数を使用します。これは this コンテキストが自動的にそれと結合されるためです
これを使って:
(videos) => {
this.setState({ videos: videos });
console.log(this.state.videos);
};
の代わりに:
function(videos) {
this.setState({ videos: videos });
console.log(this.state.videos);
};
あなたは何も束縛する必要はありません、ただこのような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>
);
}
}
また使用することができます:
<button onClick={()=>this.delta()}>+</button>
または
<button onClick={event=>this.delta(event)}>+</button>
あなたがいくつかのパラメータを渡しているなら..
あなたのメソッドを '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>
);
これをコンストラクタにバインドする必要があります。また、コンストラクタを変更した場合はサーバーを再起動する必要があります。それ以外の場合は、同じエラーで終了します。
新しいイベントを this キーワードでバインドする必要があります。
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>
);
}
}
この問題には2つの解決策があります。
最初の解決策は、コンポーネントにコンストラクタを追加し、次のように関数をバインドすることです。
constructor(props) {
super(props);
...
this.delta = this.delta.bind(this);
}
だからこれを行う:
this.delta = this.delta.bind(this);
これの代わりに:
this.delta.bind(this);
2番目の解決策は、代わりに矢印関数を使用することです。
delta = () => {
this.setState({
count : this.state.count++
});
}
実際に矢印関数はしない独自のバインドthis
。矢印関数は字句的にbind
それらのコンテキストなので、this
は実際に元のコンテキストを参照します。
バインド機能の詳細については:
矢印機能の詳細について:
追加中
onClick = {this.delta.bind(this)}
問題を解決します。このエラーはES6クラスの関数を呼び出そうとしたときに発生するので、メソッドをバインドする必要があります。
このエラーはさまざまな方法で解決できます。
ES5 構文を使用している場合は、 React js Documentation に従って、 bind methodを使用する必要があります。
上記の例では、次のようになります。
this.delta = this.delta.bind(this)
ES6 構文を使用している場合は、 bind メソッドを使用する必要はありません。次のような方法でそれを実行できます。
delta=()=>{ this.setState({ count : this.state.count++ }); }
矢印関数を使用すると、バインドを回避しやすくなりますthisキーワード。そのようです:
delta = () => {
this.setState({
count : this.state.count++
});
}
this.state = {
name: "",
email: ""
}
this.setState(() => ({
comments: comments //comments not available in state
}))
2 .(this)をチェック関数内でsetStateを実行する場合(つまり、handleChange)、関数がthisにバインドするのか、関数がarrow functionであるのかを確認する.
##これを以下の関数にバインドする3つの方法##
//3 ways for binding this to the below function
handleNameChange(e) {
this.setState(() => ({ name }))
}
// 1.Bind while callling function
onChange={this.handleNameChange.bind(this)}
//2.make it as arrow function
handleNameChange((e)=> {
this.setState(() => ({ name }))
})
//3.Bind in constuctor
constructor(props) {
super(props)
this.state = {
name: "",
email: ""
}
this.handleNameChange = this.handleNameChange.bind(this)
}
この質問にはすでに解決策がありましたが、それを明確にするために私の意見を共有したいと思います。
/*
* 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() {
//....
}
}
バインドステートメントを、必要なものから変更してください。=> this.delta = this.delta.bind(this);
<!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>