@zlodiak

Почему теряется контекст в обработчике?

Есть поле input, на него я вешаю событие 'keyup', после наступления которого происходит добавление текста этого инпута в store. Проблема в том, что в функции addTodo значение текста становится пустым(это видно по выводу в консоль). В результате в store уходит пустая строка.

function Header(props) {
  const [title, setTitle] = useState('');
  const titleRef = React.createRef();
  const keyCodeEnter = 13;

  useEffect(() => {
    titleRef.current.addEventListener('keyup', addTodo);
    return () => titleRef.current.removeEventListener('keyup', addTodo);
  }, [])

  function addTodo(e) {
    console.log(title)    // ТУТ ПУСТО
    if(e.keyCode === keyCodeEnter) {
      props.addTodoCreator({
        title: title,
        isCompleted: false,
        color: 0,
      });
    }
  }

  return (
    <>
      <input 
        type="text" 
        value={ title } 
        onChange={ e => setTitle(e.target.value) } 
        ref={ titleRef }
      />
    </>
  );
}


Помогите пожалуйста сделать так чтобы в store уходил текст, который пользователь ввёл в инпут.
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
Wondermarin
@Wondermarin
1. Зачем вы вешаете слушатель на реф?
useEffect(() => {
  titleRef.current.addEventListener('keyup', addTodo); // <-- ???
  return () => titleRef.current.removeEventListener('keyup', addTodo);
}, [])

2. Зачем вы используете фрагмент, когда возвращаете всего один элемент?
return (
   <> // <-- ???
    <input 
      type="text" 
      value={ title } 
      onChange={ e => setTitle(e.target.value) } 
      ref={ titleRef }
    />
  </> // <-- ???
);

3. Не используйте свойство keyCode оно является устаревшим, вместо него вы можете использовать key.
function addTodo(e) {
  if(e.keyCode === keyCodeEnter) { // <-- e.key === "Enter"
    props.addTodoCreator({
      title: title,
      isCompleted: false,
      color: 0,
    });
  }
}


Измените ваш код на этот:
const Header = ({ addTodoCreator }) => {
  const [title, setTitle] = useState("");

  const addTodo = (e) => {
    if (e.key === "Enter") {
      addTodoCreator({
        title: title,
        isCompleted: false,
        color: 0,
      });
    }
  };

  return (
    <input
      type="text"
      value={title}
      onChange={(e) => setTitle(e.target.value)}
      onKeyUp={addTodo}
    />
  );
};
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы