React JS警告:propType失败,输入不受控制

时间:2019-03-21 12:24:24

标签: javascript reactjs

我正在努力解决有关 React JS 的一些问题。目前正在参加速成课程,并且我一直在尝试改善todoList。我很新,希望经过8小时的故障排除后,这可能会给我带来新的视角。

我的代码-输入:

export class TodoItem extends Component {
getStyle = () => {
    return {
        background: '#233D4D',
        padding: '15px',
        borderBottom: '1px darkgray Ridge',
        textDecoration: this.props.todo.completed ? 'line-through' : 
 'none',
        color: this.props.todo.completed ? 'lightgreen' : 'white',
        fontWeight: this.props.todo.completed ? 'bold' : 'none',
    }
}

render() {
    const { title } = this.props.todo;
    return (
        <div style={this.getStyle()}>
            <p>
                <input type="checkbox" onChange= . 
    {this.props.markComplete.bind(this)} checked= . 
    {this.props.todo.completed} /> {'  '}
                {title}
                <button style={btnStyle} onClick= . 
    {this.props.delTodo.bind(this)}><FontAwesomeIcon size="2x" icon= . 
    {faTrash} /></button>
            </p>
        </div>
      )
     }
    }

   // PropTypes
   TodoItem.propTypes = {
   Todos: PropTypes.array.isRequired,
   markComplete: PropTypes.func.isRequired,
   delTodo: PropTypes.func.isRequired
   }

我的代码-propType失败:

render() {
    const { title } = this.props.todo;
    return (
        <div style={this.getStyle()}>
            <p>
                <input type="checkbox" 
                onChange={this.props.markComplete.bind(this)} 
                checked={this.props.todo.completed} /> {'  '}
                {title}
                <button style={btnStyle} 
                onClick={this.props.delTodo.bind(this)}>
                <FontAwesomeIcon size="2x" icon={faTrash} />
                </button>
            </p>
        </div>
    )
}

// PropTypes
TodoItem.propTypes = {
    Todos: PropTypes.array.isRequired,
    markComplete: PropTypes.func.isRequired,
    delTodo: PropTypes.func.isRequired
}

在这里出现我的问题:

#1 - Prop Types

index.js:1446 Warning: Failed prop type: The prop `Todos` is marked as required in `TodoItem`, but its value is `undefined`.
in TodoItem (at Todos.js:12)

#2 - Component changing an uncontrolled input

Warning: A component is changing an uncontrolled input of type text to 
be controlled. Input elements should not switch from uncontrolled to 
controlled (or vice versa). Decide between using a controlled or 
uncontrolled input element for the lifetime of the component.`

========编辑========

在此处调用组件,传递属性和进行操作的地方

render() {
    return (
      <Router>
        <div className="App">
          <div className="container">
            <Header />
            <Route exact path="/" render={props => (
              <React.Fragment>
                <AddTodo addTodo={this.addTodo} />
                <Todos todos={this.state.todo} markComplete= . 
                  {this.markComplete}
                  delTodo={this.delTodo} />
              </React.Fragment>
            )} />
            <Route path="/about" component={About} />
          </div>
        </div>
      </Router>
    );

class Todos extends Component {
  render() {
    // Mangler håndtering af ingen elementer
    let output = undefined;
    if(this.props.todos && this.props.todos.length > 0){
      // lav object
      let output = this.props.todos.map((todo) => (
        <TodoItem key={todo.id} todo={todo} markComplete= 
   {this.props.markComplete} delTodo={this.props.delTodo} />
      ))
      return output;
       }
       return (
        <div>
          {output}
        </div>
        /*this.props.todos.map((todo) => (
          <TodoItem key={todo.id} todo={todo} markComplete= 
  {this.props.markComplete} delTodo={this.props.delTodo} />
        ))*/
      );
    }
  }

1 个答案:

答案 0 :(得分:1)

我稍微清除了代码中的混乱情况,现在它对我有用:

const TodoItem = ({title, completed, delTodo, markComplete}) => (
  <div>
    <p>
      <input type="checkbox" onChange={markComplete} checked={completed} />
      {title}
      <button onClick={delTodo}>Delete</button>
    </p>
  </div>
);

TodoItem.propTypes = {
  title: PropTypes.string.isRequired,
  completed: PropTypes.bool.isRequired,
  markComplete: PropTypes.func.isRequired,
  delTodo: PropTypes.func.isRequired
};

class Todos extends Component {
  constructor(props) {
    super(props);
    this.state = {
      todos: [
        {id: 1, title: "First", completed: false},
        {id: 2, title: "Second", completed: false},
        {id: 3, title: "Third", completed: true}
      ]
    };
  }

  markComplete = id => {
    const index = this.state.todos.findIndex(t => t.id === id);
    if (index > -1) {
      const modifiedTodos = JSON.parse(JSON.stringify(this.state.todos));
      modifiedTodos[index].completed = true;
      this.setState({todos: modifiedTodos});
    }
  };

  delTodo = id => {
    const index = this.state.todos.findIndex(t => t.id === id);
    if (index > -1) {
      const modifiedTodos = JSON.parse(JSON.stringify(this.state.todos));
      modifiedTodos.splice(index, 1);
      this.setState({todos: modifiedTodos});
    }
  };

  render() {
    return (
      <div>
        {this.state.todos
          ? this.state.todos.map(todo => (
              <TodoItem
                key={todo.id}
                title={todo.title}
                completed={todo.completed}
                markComplete={() => this.markComplete(todo.id)}
                delTodo={() => this.delTodo(todo.id)}
              />
            ))
          : null}
      </div>
    );
  }
}

关于您的代码的一些评论:

  1. [第一个错误]:通过propTypes,您将Todos作为TodoItem的属性,但是在使用TodoItem时并没有设置该属性,因为您通过{ {1}},第一个错误被抛出。
  2. [第二错误]:据我所知,当更改处理程序从.isRequired更改为某些功能时,就会发生从不受控制的输入到受控输入的更改。您没有在代码中粘贴该函数,所以我无法确定到底出了什么问题,但是我认为问题是您提供的{{1}函数undefinedmarkComplete的绑定}}通过prop。通常,这会将delTodo对象绑定到当前执行上下文(在这种情况下为类TodoItem),并且由于this没有成员函数TodoItemTodoItem本身,绑定为他们返回markComplete
  3. 下次您发布问题时,尝试编写一个最小的工作示例(MWE)。您的代码确实充斥着无关的东西。删除它,SO的人员将有更好的时间为您提供帮助。
  4. 在您的类delTodoundefined中,您没有任何状态,因此最好使用无状态功能组件(紧凑得多)。
  5. 在某些地方,您的属性名称和属性值之间有空格和点。