我目前正在尝试从此Youtube Tuorial学习React,但是它们已经过时了(2016年制造)。
预期结果
如果我单击<span> x <span>
,则浏览器控制台应显示一个console.log("helloo")
问题:
我当前的问题是,在我编译了我的React代码之后,Chrome开发者控制台日志会抛出以下错误:
这是我的文件树:
这是我的index.js文件:
import React from 'react';
import ReactDom from 'react-dom';
import TodoItem from './todoItem';
class TodoComponent extends React
.Component {
constructor(props) {
super(props);
this.state = {
todos: ["clean up", "walk doggo", "take nap"]
};
}
render() {
return (
<div>
<h1>The todo list:</h1>
<ul>
<TodoItem todos={this.state.todos}/>
</ul>
</div>);
}
}
ReactDom
.render(<TodoComponent />, document.querySelector(".todo-wrapper"));
还有我的todoItem.js文件:
import React from 'react';
import ReactDom from 'react-dom';
export default class TodoItem extends React.Component {
handleDelete(){
console.log("Hellooo");
};
render() {
let todos = this.props.todos;
todos = todos.map(function(item, index) {
return (
<li>
<div className="todo-item">
<span className="item-name">{item}</span>
<span className="item-remove" onClick={this.handleDelete}> x </span>
</div>
</li>);
});
return (<React.Fragment>{todos}</React.Fragment>)
};
}
我一直在使用Stackoverflow,reddit和Google解决此问题,但是出现的大多数结果都在解释为什么在函数内不访问“ this”并通过在构造函数内绑定“ this”来解决。但是,我没有在函数中使用任何此功能,我只想console.log(“ hello”)看看它是否有效。
感谢您的帮助和时间!
答案 0 :(得分:3)
todos.map(function(item, index) => { });
OR
class App extends React.Component {
handleDelete() {
console.log('helo');
}
render() {
let _this = this;
let todos = this.props.todos;
todos = todos.map(function(item, index) {
return (
<li>
<div className="todo-item">
<span className="item-name">{item}</span>
<span className="item-remove" onClick={_this.handleDelete} > x </span>
</div>
</li>
);
});
return (
<div>{todos}</div>
);
}
}
ReactDOM.render( <App todos={["clean up", "walk doggo", "take nap"]} /> , 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>
答案 1 :(得分:1)
那是我的朋友,因为您传递给地图的回调未“绑定”到您的类TodoItem。为什么是这样 ?这是因为您正在将简单的匿名函数传递给地图。
改为使用箭头语法,以便将传递给.map Array方法的回调自动绑定到render方法内部的this(绑定到组件):
todos = todos.map((item, index) => {
return (
<li>
<div className="todo-item">
<span className="item-name">{item}</span>
<span className="item-remove" onClick={this.handleDelete}> x </span>
</div>
</li>);
});
编辑:当您使用function(){}语法时,可以在地图的回调函数内部进行console.log(this)检查,以确保它等于全局对象
更新:
如果您不想使用箭头功能,可以将其放置在变量中,然后从回调中使用它,例如:
var myComponent = this;
todos = todos.map(function(item, idx) { /*...*/ onClick=
{myComponent.handleDelete} }
或者在您的组件上声明一个方法,将其绑定,然后将其作为回调函数传递:
class TodoItem extends ... {
constructor() {
super();
this.renderItem = this.renderItem.bind(this);
}
renderItem(item, idx) { /*...*/ }
render() {
todos = this.state.todos.map(this.renderItem);
}
答案 2 :(得分:0)
在TodoItem类中
将方法绑定到构造函数中,或使用粗箭头符号。
export default class TodoItem extends React.Component {
constructor(props){
super(props)
this.handleDelete = this.handleDelete.bind(this);
}
handleDelete(){
console.log("Hellooo");
};
.
.
.
}
或者只是使用粗箭头,如:
<span className="item-remove" onClick={()=>this.handleDelete}> x </span>
答案 3 :(得分:0)
您找到的结果正确。他们引用的this是 this .handleDelete。
调用onClick时,不提供上下文,因为在使用地图时不使用箭头功能。
箭头函数传递上下文,经典的匿名函数不传递上下文。
答案 4 :(得分:-1)
编辑:刚刚发现了实际的问题:在function
内包含map
会阻止使用this
。但是即使将map函数更改为arrow函数,您仍然需要bind()
该处理程序或使用arrow函数。
这是一个可行的例子
class App extends React.Component {
render() {
let list = [1, 2, 3]; //Can take from props
list = list.map(item => {
return (<div onClick={() => console.log(`Item ${item} Clicked`)}>{item}</div>)
});
return (
<div>
{list}
</div>
);
}
}
ReactDOM.render( <App /> , 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>
在此示例中,我希望单击的div显示带有单击数字的警报窗口,因此onClick道具变为onClick={() => this.handleClick(item)}
如果只需要看console.log
,我可以向您推荐:
console.log('helooo')}> x
class App extends React.Component {
render() {
let list = [1, 2, 3]; //Can take from props
list = list.map(function(item, index) {
return (<div onClick={() => console.log('heloo')}>{item}</div>)
});
return (
<div>
{list}
</div>
);
}
}
ReactDOM.render( <App /> , 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>
这永远不会起作用,因为函数是它自己的对象,因此this
引用该函数而不是您的类:
class App extends React.Component {
handleClick = () => {
console.log('helooo');
}
render() {
let list = [1, 2, 3]; //Can take from props
list = list.map(function(item, index) {
return (<div onClick={this.handleClick}>{item}</div>)
});
return (
<div>
{list}
</div>
);
}
}
ReactDOM.render( <App /> , 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>
.bind()
您的处理程序,或将其更改为箭头功能。todo
映射需要使用箭头功能来完成。或者,请参阅Rohan Veer的答案,该答案将.this
的引用复制到变量中我只是在这里提供一个可运行的示例