Z
Z
zlodiak2020-11-03 01:55:39
JavaScript
zlodiak, 2020-11-03 01:55:39

Why is the context lost in the handler?

There is an input field, I hang the 'keyup' event on it, after which the text of this input is added to the store. The problem is that in the addTodo function, the text value becomes empty (this can be seen from the output to the console). As a result, an empty string is left in 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 }
      />
    </>
  );
}


Please help to make the text that the user entered into the input leave in the store.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
W
Wondermarin, 2020-11-03
@zlodiak

1. Why are you attaching a listener to a ref?

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

2. Why are you using a fragment when you only return one element?
return (
   <> // <-- ???
    <input 
      type="text" 
      value={ title } 
      onChange={ e => setTitle(e.target.value) } 
      ref={ titleRef }
    />
  </> // <-- ???
);

3. Don't use the keyCode property, it's deprecated, you can use key instead .
function addTodo(e) {
  if(e.keyCode === keyCodeEnter) { // <-- e.key === "Enter"
    props.addTodoCreator({
      title: title,
      isCompleted: false,
      color: 0,
    });
  }
}

Change your code to this:
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}
    />
  );
};

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question