我目前正在学习React,并且正在关注guy Youtube Videos。
但是,它们已经过时了,很难与旧的代码相处。我已经尝试了一些Stackoverflow和Google解决方案,但是它们没有帮助。
现在我在如何访问在todo
内声明的变量render()
并在handleDelete
之外使用我的函数render()
更新变量的问题上呢? / p>
我的目标是删除我单击的项目。
我已经尝试在构造函数()中设置变量,但是无法为它赋予this.props.todos的值。
我的代码:
import React from 'react';
import ReactDom from 'react-dom';
export default class TodoItem extends React.Component {
handleDelete(item){
let updatedTodos = this.props.todos;
updatedTodos = updatedTodos.filter((val,index) => {
return item !== val;
})
todos = updatedTodos;
};
render() {
//Add all this.props items
let todos = this.props.todos;
todos = todos.map((item, index) => {
return (
<li>
<div className="todo-item">
<span className="item-name">{item}</span>
<span className="item-remove" onClick={this.handleDelete.bind(this, item)}> x </span>
</div>
</li>);
});
return (<React.Fragment>{todos}</React.Fragment>)
};
}
(此代码后来导出到index.js中,并在其中使用Babel进行编译)
感谢您抽出宝贵的时间!
更新:
这里是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"));
答案 0 :(得分:3)
TodoComponent
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"]
};
}
handleDelete(item){
let todos = this.state.todos;
todos= todos.filter((todo) => todo !== item);
this.setState((prevState) => ({
todos: todos
}));
};
render() {
return (<div>
<h1>The todo list:</h1>
<ul>
<TodoItem todos={this.state.todos} handleDelete={this.handleDelete}/>
</ul>
</div>);
}
}
ReactDom.render(<TodoComponent/>, document.querySelector(".todo-wrapper"));
Todo物品
import React from 'react';
import ReactDom from 'react-dom';
export default class TodoItem extends React.Component {
render() {
return (
this.props.todos.map((item) => {
return (
<li>
<div className="todo-item">
<span className="item-name">{item}</span>
<span className="item-remove" onClick={() => this.props.handleDelete(item)}> x </span>
</div>
</li>
)
}))
}
}
您的代码在TodoItem
中出现问题,您试图删除TodoItem
中无法访问状态的项目。而且,如果您在组件中执行某些操作,并且想要使更改反映出来,则必须重新渲染组件。当您的状态更改时,这是可能的。与相应更改相关的组件将重新呈现自己
答案 1 :(得分:1)
我没有测试过,所以可能会有一些错别字,但是您必须这样做
import React from 'react';
import ReactDom from 'react-dom';
export default class TodoItem extends React.Component {
handleDelete(item){
this.props.updateTodos(item)
};
render() {
//Add all this.props items
let todos = this.props.todos;
todos = todos.map((item, index) => {
return (
<li>
<div className="todo-item">
<span className="item-name">{item}</span>
<span className="item-remove" onClick={this.handleDelete.bind(this, item)}> x </span>
</div>
</li>);
});
return (<React.Fragment>{todos}</React.Fragment>)
};
}
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"]
};
this.updateTodos =this.updateTodos.bind(this);
}
updateTodos(item){
this.setState({todos :this.state.todos.filter((val,index) => {
return item !== val;
})})
}
render() {
return (<div>
<h1>The todo list:</h1>
<ul>
<TodoItem todos={this.state.todos} updateTodos ={this.updateTodos}/>
</ul>
</div>);
}
}
ReactDom.render(<TodoComponent/>, document.querySelector(".todo-wrapper"));
答案 2 :(得分:1)
我为您建议另一种方法。您需要更好地思考一些问题。首先,建议您将todo
作为对象,并让它们具有id
和text
属性。
第二,您有一个单独的组件,但您将整个todos
传递给它。取而代之的是,映射您的todos
,然后将每个todo
传递给您的组件。这样,您对一切的管理将变得更加容易。
根据您的情况,您需要一个删除处理程序来传递您的TodoItem
,然后使用该处理程序来执行操作。
最后,您的TodoItem
不必是一个类组件,因此我已对其进行了更改。
这是一个可行的示例。我已根据我的建议更改了您的代码。
class Todos extends React.Component {
state = {
todos: [
{ id: 1, text: "foo" },
{ id: 2, text: "bar" },
{ id: 3, text: "baz" },
]
}
deleteTodo = ( todo ) => {
const newTodos = this.state.todos.filter( el => el.id !== todo.id );
this.setState({ todos: newTodos });
}
render() {
const { todos } = this.state;
return (
<div>
<ul>
{
todos.map( todo => <TodoItem key={todo.id} todo={todo} deleteTodo={this.deleteTodo} /> )
}
</ul>
</div>
)
}
}
const TodoItem = props => {
const handleDelete = () => props.deleteTodo(props.todo);
return (
<li onClick={handleDelete}>{props.todo.text} x</li>
)
};
ReactDOM.render(<Todos />, 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>
此外,昨晚我为另一个问题写了一个小例子。但是它越来越大,我没有发布。但是,这是一个简单的小型Todo示例。当然必须进行一些改进,但是您可以作为示例进行研究。
https://codesandbox.io/s/01v3kmp9vv
修改
如果您不想使用class-fields
并安装另一个Babel插件,只需使用以下内容更改相关部分:
class Todos extends React.Component {
consturctor( props ) {
super( props );
this.state = {
todos: [
{ id: 1, text: "foo" },
{ id: 2, text: "bar" },
{ id: 3, text: "baz" },
],
}
}
....rest of the code