@Artem641

Как отменить событие для конкретного элемента?

Всем привет. Есть состояние editMode, в зависимости от которого мы показываем span или input. На Input повешено событие onBlur, и при уходе фокуса с input ( пользователь передумал редактировать данные ) editMode устанавливается в false. Но если в режиме редактирования кликнуть по кнопке save, срабатывает onBlur. Вопрос в том, как прервать это событие только для кнопки. Я знаю, что нужно применить event.stopPropagation(), но не пойму как именно это надо сделать.
Вот мой item:
import { TodoType } from '../../App'
import { MyButton } from '../UI/MyButton/MyButton'
import { MyInput } from '../UI/MyInput/MyInput'
//@ts-ignore
import s from './TodoItem.module.css'
import { ChangeEvent, useState } from 'react'

type TodoItemPropsType = {
  todo: TodoType
  todos: Array<TodoType>
  setTodos: any
}

export const TodoItem: React.FC<TodoItemPropsType> = ({
  todo,
  setTodos,
  todos,
}) => {
  const [editMode, setEditMode] = useState(false)
  const [editTodoText, setEditTodoText] = useState(todo.title)

  const updateTodo = (event: ChangeEvent) => {
    setTodos(
      todos.map((t) => {
        if (t.id == todo.id) {
          return { ...t, title: editTodoText }
        }
        return t
      })
    )
    setEditMode(false)
  }

  const setTodoStatus = (todoId: number) => {
    setTodos(
      todos.map((t) => {
        if (t.id == todo.id) {
          return { ...t, status: !todo.status }
        }
        return t
      })
    )
  }

  const deleteTodo = (todoId: number) => {
    setTodos(todos.filter((t) => t.id !== todoId))
  }

  return (
    <div className={s.todoItem}>
      <div>
        {editMode ? (
          <div>
            <MyInput
              value={editTodoText}
              onChange={(e: ChangeEvent<HTMLInputElement>) =>
                setEditTodoText(e.currentTarget.value)
              }
              onBlur={() => {
                setEditMode(false)
              }}
              autoFocus={true}
              type="text"
            />
            <MyButton onClick={updateTodo}>Save</MyButton>
          </div>
        ) : (
          <span className={todo.status ? s.completed : ''}>{todo.title}</span>
        )}
      </div>
      <div>
        <div>
          <label id="status" htmlFor="input">
            Completed{' '}
          </label>
          <input
            onChange={() => {
              setTodoStatus(todo.id)
            }}
            checked={todo.status}
            type="checkbox"
            name=""
            id="status"
          />
        </div>
        <div>
          <MyButton small={true} onClick={() => setEditMode(true)}>
            Edit
          </MyButton>
        </div>
        <div>
          <MyButton small={true} onClick={() => deleteTodo(todo.id)}>
            Delete
          </MyButton>
        </div>
      </div>
    </div>
  )
}


Моя кастомная кнопка:
//@ts-ignore
import s from './MyButton.module.css'

type MyButtonPropsType = {
  children: string
  onClick?: any
  small?: boolean
  disabled?: boolean
}

export const MyButton: React.FC<MyButtonPropsType> = ({
  children,
  small,
  ...props
}) => {
  return (
    <button className={`${s.button} ${small ? s.small : ''}`} {...props}>
      {children}
    </button>
  )
}
  • Вопрос задан
  • 408 просмотров
Решения вопроса 1
dasha_programmist
@dasha_programmist
ex Software Engineer at Reddit TS/React/GraphQL/Go
замени button onClick на onMouseDown
<MyButton onMouseDown={updateTodo}>Save</MyButton>
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
szQocks
@szQocks
Просто используй preventDefaultв updateTodo
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы