Как отменить изменения в div ContentEditable в дочерних компонентах React? - PullRequest
0 голосов
/ 08 января 2019

У меня есть следующий HOC:

class SectionContainer extends Component {
  ... // class internal methods
  render () {
    return (
      <section>
        {this.props.children}
      </section>
      <Snackbar
        ...
        action={snackbarAction} />
    );
  }
}

Теперь у меня есть, например, компонент Categories, где я реализую вышеуказанный HOC:

class Categories extends Component {
  ... // class internal methods
  render () {
    const {
      categories,
      error
    } = this.props;

    let content = error ? <p>Oops, couldn't load categories...</p> : <Spinner />;

    if ( categories.length > 0 ) {
      content = (
        categories.map(category => {
          return (
            <Category
              displayIn='panel'
              category={category}
              key={category.id}
              textChanged={this.onTextChangeHandler}
              blurred={this.onBlurHandler} />
          );
        })
      );
    }
    return (
      <SectionContainer searchVisible ref='sectionContainer'>
        {content}
      </SectionContainer>
    );
  }
}

Категории извлекаются из Firebase и сохраняются в состоянии.

И, наконец, вот один компонент категории:

const category = (props) => {
  const nameRef = React.createRef();
  const colorRef = React.createRef();
  const imageRef = React.createRef();

  let currentCategory = null;
  const onFocusHandler = (category) => {
    setCurrentCategory(category);
  };
  const onBlurHandler = (originalCategory) => {
    setCurrentCategory(originalCategory);
    props.blurred(originalCategory, currentCategory);
  };

  const setCurrentCategory = category => {
    currentCategory = updateObject(category, {
      name: nameRef.current.innerText,
      color: colorRef.current.innerText,
      image: imageRef.current.dataset.image
    });
  };

...

return (
  <Card onFocus={() => onFocusHandler(props.category)}>
    <div className='CategoryImage'>
      <div
        id={'iamge-' + props.category.id}
        ref={imageRef}
        className='Image'
        data-image={props.category.image}></div>
    </div>
    <CardContent className='CardContent'>
      <RootRef rootRef={nameRef}>
        <Typography
          contentEditable={true}
          suppressContentEditableWarning={true}
          id={'name-' + props.category.id}
          onBlur={() => onBlurHandler(props.category)}
          onInput={() => props.textChanged(props.category)}>
            {props.category.name}
        </Typography>
      </RootRef>
      <RootRef rootRef={colorRef}>
          <Typography
            contentEditable={true}
            suppressContentEditableWarning={true}
            id={'color-' + props.category.id}
            onBlur={() => onBlurHandler(props.category)}
            onInput={() => props.textChanged(props.category)}>
              {props.category.color}
          </Typography>
        </RootRef>
    </CardContent>
  </Card>);
};

Обычно, когда я начинаю редактировать текст в одной из этих категорий, я сразу получаю снэк-бар с 2 кнопками - Сохранить и Отменить. Нажатие на Сохранить сохраняет все изменения в Firebase.

Вопрос заключается в следующем: когда я нажимаю Отменить, как я могу отменить все внесенные изменения и вернуть категории в исходное состояние, не обновляя страницу (я пробовал, это работало, но в этом случае UX не очень хорошо, плюс я хочу сохранить еще один звонок на сервер). Я попытался переназначить состояние путем глубокого копирования его в новый массив и замены оригинала старым, но получил сообщение о том, что никаких изменений не обнаружено (ну, очевидно). Есть идеи?

...