简体   繁体   English

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

[英]React JS Warnings: Failed propType and uncontrolled input

I'm struggling to fix some issues regarding React JS . 我正在努力解决有关React JS的一些问题。 Currently worked on a crash course, and I've been trying to improve the todoList. 目前正在参加速成课程,并且我一直在尝试改善todoList。 I'm very new and hopefully this might give me a new perspective after already 8 hours of troubleshooting. 我很新,希望经过8个小时的故障排除后,可能会给我带来新的认识。

My code - Input: 我的代码-输入:

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
   }

My code - Failed propType: 我的代码-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
}

Heres my issues: 这是我的问题:

#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.`

======== EDIT ========= ========编辑=========

Heres where the components called, properties passed and the manipulation: 这里是组件调用,传递的属性和操作的地方:

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} />
        ))*/
      );
    }
  }

I cleaned the mess in your code a bit and it is now working for me: 我稍微清除了代码中的混乱情况,现在对我有用:

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>
    );
  }
}

Some comments about your code: 关于您的代码的一些注释:

  1. [FIRST ERROR]: Via propTypes you had Todos as property for TodoItem , but you didn't set that property when using TodoItem and because you set it as required with .isRequired , the first error had been thrown. [第一个错误]:通过propTypes你有Todos作为财产TodoItem ,但使用时您没有设置该属性TodoItem因为你把它设置为与所需.isRequired ,第一个错误被抛出。
  2. [SECOND ERROR]: As far as I can tell, changing from uncontrolled to controlled inputs happens, when the change handler changes from undefined to some function. [第二错误]:据我所知,当更改处理程序从未undefined更改为某些功能时,就会发生从不受控制的输入到受控输入的更改。 You didn't paste your code with that function, so I can not tell, what was going wrong exactly, but I think the problem is the binding of the functions markComplete and delTodo you provided TodoItem via prop. 您没有使用该函数粘贴代码,所以我无法确定到底出了什么问题,但是我认为问题是您通过prop提供的TodoItem函数markCompletedelTodo的绑定。 Usually this binds the this object to the current execution context (class TodoItem in this case) and because TodoItem has no member functions markComplete and delTodo itself, the binding returns undefined for them. 通常,这会this对象绑定到当前的执行上下文(在这种情况下为TodoItem类),并且由于TodoItem没有成员函数markCompletedelTodo本身,因此绑定返回的undefined
  3. Next time you post a question try to write a minimal working example (MWE). 下次您发布问题时,尝试编写一个最小的工作示例(MWE)。 Your code is really bloated with irrelevant stuff. 您的代码确实充斥着无关的东西。 Remove that and the folks here at SO will have a much better time helping you. 删除它,SO的人们将有更好的时间为您提供帮助。
  4. In your classes Todos and TodoItem you don't have any state, so better use stateless function components (much more compact). 在您的类TodosTodoItem您没有任何状态,因此最好使用无状态功能组件(紧凑得多)。
  5. On some places you had white spaces and dots separating your property names and your property values. 在某些地方,您的属性名称和属性值之间存在空格和点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM