Draft.js добавление гиперссылки с помощью applyEntity, похоже, не работает

#reactjs #functional-programming #draftjs #draft-js-plugins

#reactjs #функциональное программирование #draftjs #черновик-js-плагины

Вопрос:

Я некоторое время работал над этой проблемой, и я надеюсь, что это не ошибка.

Я тестирую текстовый редактор, используя Draft.js , и я просто хотел бы, чтобы мои пользователи добавляли гиперссылки на свои статьи, поэтому я создаю функцию для этого, изменяя содержимое состояния редактора.

 const addLlink = (e) => {
    e.preventDefault();
    const contentState = editorState.getCurrentContent();
    const contentStateWithEntity = contentState.createEntity(
        'LINK', 'MUTABLE', {url: 'https://www.amazon.com'} // link for testing only
    );
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
    const contentStateWithLink = Modifier.applyEntity(
        contentStateWithEntity,
        editorState.getSelection(),
        entityKey
    );
    // tried with and without styling
    const styledContentStateWithLink = Modifier.applyInlineStyle(
        contentStateWithLink,
        editorState.getSelection(),
        'HYPERLINK'
    );
    const newState = EditorState.set(editorState, {
        currentContent: styledContentStateWithLink
    });

    setEditorState(newState);
    // Also tried: setEditorState(RichUtils.toggleLink(newState, newState.getSelection(), entityKey));
}
  

Когда я запускаю его, я просто использую кнопку Evergreen-ui:

 <Button onMouseDown={addLlink} appearance="minimal">Link</Button>
  

Стиль, который я реализую с использованием объекта-модификатора, работает, но, похоже, я не могу заставить ссылку действительно работать. Следует отметить, что плагин link в виде пакета, который отлично работает, но предназначен только для обнаружения введенных / вставленных URL-адресов (не встроенных в текст).

У кого-нибудь есть реальный рабочий пример или предложения о том, что я могу делать неправильно, для ссылок, использующих функциональное программирование React?

Ответ №1:

Оказывается, мне нужно было добавить декоратор, чтобы объект был обнаружен. Я разместил этот код выше / за пределами моего компонента редактора:

 const findLinkEntities = (contentBlock, callback, contentState) => {
contentBlock.findEntityRanges(
  (character) => {
    const entityKey = character.getEntity();
    return (
      entityKey !== null amp;amp;
      contentState.getEntity(entityKey).getType() === 'LINK'
    );
  },
  callback
);


}
const Link = (props) => {
    const {url} = props.contentState.getEntity(props.entityKey).getData();
    return (
      <a href={url} >
        {props.children}
      </a>
    );
};

const strategyDecorator = new CompositeDecorator([
    {
      strategy: findLinkEntities,
      component: Link,
    },
]);
  

По сути, он обнаруживает объекты ссылок и преобразует их в элементы, когда вы устанавливаете новое содержимое с помощью EditorState:

 const newState = EditorState.set(editorState, {
        currentContent: styledContentStateWithLink,
        decorator: strategyDecorator
    });
  

Комментарии:

1. рад, что вы пришли к решению, пожалуйста, примите свой собственный ответ, чтобы люди знали, что это решено

2. Спасибо! Просто жду истечения времени, чтобы я мог это сделать.

Ответ №2:

Согласно официальному примеру, вам нужно добавить декоратор, чтобы найти объекты и применить компонент Link

 const decorator = new CompositeDecorator([
  {
    strategy: findLinkEntities,
    component: Link,
  },
]);
  

И поскольку вы используете плагин linkify, вы должны передать декоратор в редактор плагинов

 import Editor from "draft-js-plugins-editor";
import createLinkifyPlugin from "draft-js-linkify-plugin";
import "draft-js-linkify-plugin/lib/plugin.css";

...
<Editor
  decorators={[decorator]}
  editorState={editorState}
  onChange={setEditorState}
  plugins={[linkifyPlugin]}
/>
...
  

вы можете ознакомиться с рабочим примером здесь https://codesandbox.io/s/test-selection-decorator-draft-js-link-0lblg?file=/src/ExtendedEditor.js

Комментарии:

1. Похоже, мы работали над ответом одновременно! Спасибо 🙂

2. @Bennybear да, Иисус! каковы шансы 😂 🙃