Предупреждения React JS: Failed propType и неконтролируемый ввод

Я пытаюсь исправить некоторые проблемы, связанные с Реагировать 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} />
        ))*/
      );
    }
  }

Покажите нам, где вы вызываете этот компонент в своем коде, как вы передаете ему свойства и как вы манипулируете им.

Vencovsky 21.03.2019 13:27

@Vencovsky Большое спасибо, я все еще новичок. Я обновил код, чтобы отобразить то, что, как мне кажется, вы упомянули.

Mads Frost 21.03.2019 13:41
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
262
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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, и поскольку вы установили его как требуется с .isRequired, возникла первая ошибка.
  2. [ВТОРАЯ ОШИБКА]: Насколько я могу судить, переход с неуправляемых на контролируемые входы происходит, когда обработчик изменений меняется с undefined на какую-то функцию. Вы не вставили свой код с этой функцией, поэтому я не могу сказать, что именно пошло не так, но я думаю, что проблема в привязке функций markComplete и delTodo, которые вы предоставили TodoItem через проп. Обычно это привязывает объект this к текущему контексту выполнения (в данном случае классу TodoItem), и поскольку TodoItem не имеет функций-членов markComplete и самого delTodo, привязка возвращает для них undefined.
  3. В следующий раз, когда вы зададите вопрос, попробуйте написать минимальный рабочий пример (MWE). Ваш код действительно раздут ненужными вещами. Удалите это, и ребятам из SO будет гораздо лучше помогать вам.
  4. В ваших классах Todos и TodoItem у вас нет состояния, поэтому лучше используйте функциональные компоненты без состояния (намного более компактные).
  5. В некоторых местах у вас были пробелы и точки, разделяющие имена ваших свойств и их значения.

Эй, извините за поздний ответ, эти комментарии были действительно приятными и полезными, большое спасибо :) !!

Mads Frost 27.03.2019 21:45

Другие вопросы по теме