Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我在这个我';我在做什么?_Javascript_Reactjs - Fatal编程技术网

Javascript 我在这个我';我在做什么?

Javascript 我在这个我';我在做什么?,javascript,reactjs,Javascript,Reactjs,是的,我是新手,我正在尝试从头开始制作(臭名昭著的?)待办应用程序。到目前为止,我只有一个待办事项组件,然后是主应用程序。以下是我的代码-首先是Todo组件: import PropTypes from 'prop-types'; class Todo extends Component { static defaultProps = { completed: false, } static propTypes = { complet

是的,我是新手,我正在尝试从头开始制作(臭名昭著的?)待办应用程序。到目前为止,我只有一个待办事项组件,然后是主应用程序。以下是我的代码-首先是Todo组件:

import PropTypes from 'prop-types';

class Todo extends Component {

    static defaultProps = {
        completed: false,
    }

    static propTypes = {
        completed: PropTypes.bool.isRequired,
        // name: PropTypes.string.isRequired,
    }

    constructor(props){
        super(props)

        this.state = {
            completed: false,
        }
    }

    render(){
        return (
            <div>
                {!this.state.completed && <div>
                    <span>{this.props.name}</span>
                    <input type="checkbox" onClick={() => {this.markCompleted()}}/>
                </div>}
            </div>
        )
    }

    markCompleted = () => {
        this.setState((currentState) => {
            return {
                completed: !currentState.completed
            }
        })
    }
}

export default Todo;
从“道具类型”导入道具类型;
类Todo扩展组件{
静态defaultProps={
已完成:错误,
}
静态类型={
已完成:PropTypes.bool.isRequired,
//名称:PropTypes.string.isRequired,
}
建造师(道具){
超级(道具)
此.state={
已完成:错误,
}
}
render(){
返回(
{!this.state.completed&&
{this.props.name}
{this.markCompleted()}}/>
}
)
}
标记已完成=()=>{
this.setState((当前状态)=>{
返回{
已完成:!currentState.completed
}
})
}
}
导出默认Todo;
然后是主要的应用程序组件

import React from 'react';
import Todo from './Todo';
import './App.css';

class App extends React.Component {

  constructor(props){
    super(props)
      this.state = {
        todos: [{id: 1, name: 'take out trash'}, {id: 2, name: 'feed the cat'}]
      }
  }

  render(){
    let textInput;
    const todos = this.state.todos.map(todo => <Todo key={todo.id} name={todo.name} completed={todo.completed}/>)
    return (
      <div className="App">
         <input type="text" ref={(el) => {textInput = el}} />
         <button onClick={() => {this.addTodo(textInput.value)}}>Click to Add a Todo</button>
        {todos}
      </div>
    );
  }

  addTodo = (todoName) => {
    const newTodo = {id: this.state.todos.length + 1, name: todoName};
    const todos = this.state.todos.map(todo => <Todo key={todo.id} name={todo.name} completed={todo.completed}/>)
    todos.push(newTodo)
    console.log(this.state.todos);
      this.setState({
        todos
      })
      // console.log(todos)
    }
}

export default App;
从“React”导入React;
从“/Todo”导入Todo;
导入“/App.css”;
类应用程序扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
todos:[{id:1,名称:'拿出垃圾'},{id:2,名称:'喂猫'}]
}
}
render(){
让文本输入;
const todos=this.state.todos.map(todo=>)
返回(
{textInput=el}}/>
{this.addTodo(textInput.value)}}>单击以添加Todo
{todos}
);
}
addTodo=(todoName)=>{
const newTodo={id:this.state.todos.length+1,name:todoName};
const todos=this.state.todos.map(todo=>)
todos.push(纽托多)
console.log(this.state.todos);
这是我的国家({
待办事项
})
//控制台日志(todos)
}
}
导出默认应用程序;

所以我留下了一个难题。在初始渲染时,todos数组的状态映射得很好。但是,当我键入一个todo并单击按钮添加该todo时,其他todo的所有名称都将消失,并且只显示上次按下的todo的名称。因此,如果我要添加一个todo“支付账单”,那么“拿出垃圾”和“喂猫”的复选框将仍然可见,但这些todo的名称将不再可见。我可以点击复选框删除TODO,但我希望我的TODO阵列能够配合。我想我还应该使用
.filter
来正确地筛选出完成状态标记为
true
的TODO。其他名称是否因为我在
addTodo
方法中添加的
todoName
参数而消失?这是否会导致之前所有的todo名称都未定义?我真的在努力学习,我愿意接受所有帮助和改进建议。我会要求我们使用我已经使用过的代码,因为我已经看到其他人以前是如何制作todo应用程序的,我不想只是复制和观察其他人的代码,因为我觉得这有损于我的学习。提前感谢您的帮助

我在
App
课程上做了一些修改:

addTodo
中,简化它,您可以按如下方式推送状态数组:

addTodo=(todoName)=>{
const newTodo={id:this.state.todos.length+1,name:todoName};
这是我的国家({
todos:[…this.state.todos,newTodo]
})
console.log(this.state.todos);
}
对于渲染也一样,您不需要使用辅助TODO,只需像之前那样映射状态即可

render(){
让文本输入;
返回(
{textInput=el}}/>
{this.addTodo(textInput.value)}}>单击以添加Todo
{this.state.todos.map(todo=>)}
);
}

谢谢-这非常有效!我想问一下,为什么我们可以将
todos
的状态设置为当前状态为
todos
的数组,然后设置
newTodo
?我知道我是新手,所以我认为将
newTodo
推到
this.state.todos
中可以完成同样的任务。我可以问一下,为什么你的解决方案会像我的解决方案那样工作吗?这个问题可能太模糊,也可能不太模糊。请回顾以下内容:有两件事是错误的,映射没有正确完成,如果要复制数组,可以使用slice()或[…arraytopcopy]const todos=This.state.todos.slice();const todos=[…this.state.todos]您可以使用map,但它效率不高。稍后,您将设置状态,而不对todos状态进行任何分配,这样它就不会得到更新。如果您有更多疑问,请打开一个新问题。