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

Javascript React JS警告:propType失败,输入不受控,javascript,reactjs,Javascript,Reactjs,我正在努力解决一些关于React JS的问题。目前正在参加速成班,我一直在努力提高托多利斯特。我是个新手,希望这能给我一个新的视角,在已经8个小时的故障排除之后 我的代码-输入: export class TodoItem extends Component { getStyle = () => { return { background: '#233D4D', padding: '15px', borderBottom: '1px

我正在努力解决一些关于React JS的问题。目前正在参加速成班,我一直在努力提高托多利斯特。我是个新手,希望这能给我一个新的视角,在已经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
   }
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} />
        ))*/
      );
    }
  }
render(){
返回(
(
)} />
);
类Todos扩展组件{
render(){
//Mangler håndering af ingen元件
让输出=未定义;
if(this.props.todos&&this.props.todos.length>0){
//lav对象
让输出=this.props.todos.map((todo)=>(
))
返回输出;
}
返回(
{output}
/*this.props.todos.map((todo)=>(
))*/
);
}
}

我清理了一下您代码中的混乱,现在它对我起作用了:

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>
    );
  }
}
const TodoItem=({title,completed,delTodo,markComplete})=>(

{title}
删除

); TodoItem.propTypes={ 标题:PropTypes.string.isRequired, 已完成:PropTypes.bool.isRequired, markComplete:PropTypes.func.isRequired, delTodo:PropTypes.func.isRequired }; 类Todos扩展组件{ 建造师(道具){ 超级(道具); 此.state={ 待办事项:[ {id:1,标题:“第一”,完成:false}, {id:2,标题:“第二”,完成:false}, {id:3,标题:“第三”,完成:真} ] }; } markComplete=id=>{ const index=this.state.todos.findIndex(t=>t.id==id); 如果(索引>-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); 如果(索引>-1){ const modifiedTodos=JSON.parse(JSON.stringify(this.state.todos)); 修改后的路径拼接(索引1); this.setState({todos:modifiedTodos}); } }; render(){ 返回( {this.state.todos ?this.state.todos.map(todo=>( this.markComplete(todo.id)} delTodo={()=>this.delTodo(todo.id)} /> )) :null} ); } }
关于您的代码的一些评论:

  • [第一个错误]:通过propTypes,您将
    Todos
    作为
    TodoItem
    的属性,但在使用
    TodoItem
    时未设置该属性,并且由于您使用
    将其设置为所需。isRequired
    ,因此引发了第一个错误
  • [第二个错误]:据我所知,当更改处理程序从
    undefined
    更改为某个函数时,会发生从非受控输入到受控输入的更改。您没有将代码与该函数粘贴在一起,因此我无法确切判断出问题所在,但我认为问题在于您通过prop提供的函数
    markComplete
    delTodo
    的绑定。通常,这会将
    this
    对象绑定到当前执行上下文(在本例中为class
    TodoItem
    ),并且由于
    TodoItem
    没有成员函数
    markComplete
    delTodo
    本身,绑定会为它们返回
    undefined
  • 下次发布问题时,请尝试编写一个最小工作示例(MWE)。你的代码中充斥着不相关的东西。去掉这个,这里的人会有更好的时间来帮助你
  • 在类
    Todos
    TodoItem
    中,您没有任何状态,因此最好使用无状态函数组件(更紧凑)
  • 在某些地方,属性名称和属性值之间用空格和圆点分隔

  • 向我们展示您在代码中调用该组件的位置、如何向其传递属性以及如何操作它。@Vencovsky非常感谢您,我还是新手。我更新了代码,以显示我认为是你提到的内容。嘿,很抱歉回复太晚,这些评论真的很好,很有帮助,非常感谢:)!!