В этом руководстве будут рассмотрены шаги по отправке данных Draft.js на сервер с помощью запроса POST, а затем как получить и отобразить эти данные с помощью запроса GET.
Я использую серверную часть Express, базу данных MongoDB и интерфейс React. Для этого потребуются некоторые базовые знания Draft.js - существует множество отличных руководств по настройке.
Зависимости: react
, axios
, draft-js
Структура:
- Компонент AddPost с редактором Draft.js →
useSubmit()
hook для обработки запроса POST. - Компонент PostGallery для отображения сообщений →
usePosts()
крючок для обработки получения сообщений.
Предварительные требования для настройки маршрутов GET и POST
Во-первых, убедитесь, что у вас есть установленный маршрут, который может принимать запросы POST. Я собираюсь отправлять заметки из Draft.js, поэтому мой маршрут называется /posts
. Объяснение того, как настроить серверную часть, выходит за рамки этой статьи, но все схемы, маршруты и контроллеры находятся в репозитории.
Экспресс-пользователи: убедитесь, что у вас настроено промежуточное ПО для синтаксического анализа тела, прежде чем выполнять запросы POST:
app.use(express.json()); app.use(express.urlencoded({extended: true}));
Верхняя строка позволит вам отправлять объекты JSON в теле запроса, а нижняя строка позволит вам отправлять строки, массивы и вложенные объекты.
1. Данные POST Draft.js
Отправьте данные Draft.js на сервер с помощью POST-запроса
Я хочу опубликовать свои данные, когда нажимаю кнопку сохранения в моем интерфейсе React. Я собираюсь прикрепить к этой кнопке функцию, которая будет отправлять запрос POST. Я собираюсь сохранить его на Submit в его родительском компоненте.
import React from 'react'; import RichEditor from '../components/editor/RichEditor'; import Button from '../components/Button'; import useSubmit from '../hooks/useSubmit'; import useRichEditor from '../hooks/useRichEditor'; const Add = () => { const { editorState, onNoteChange, clearEditor, mapKeyToEditorCommand, handleKeyCommand, toggleInlineStyle, toggleBlockType } = useRichEditor(); const { submitPage } = useSubmit(); const handleSubmit = async (e) => { e.preventDefault(); const data = editorState.getCurrentContent(); await submitPage(data); }; return ( <form handleSubmit={handleSubmit}> <RichEditor editorState={editorState} onNoteChange={onNoteChange} clearEditor={clearEditor} mapKeyToEditorCommand={mapKeyToEditorCommand} handleKeyCommand={handleKeyCommand} toggleInlineStyle={toggleInlineStyle} toggleBlockType={toggleBlockType} /> <Button kind="primary" type="submit" label="add"/> </form> ); } export default Add;
При отправке мы вызываем e.preventDefault()
, чтобы страница не обновлялась, а затем получаем весь текущий контент в редакторе с помощью editorState.getCurrentContent()
. Затем мы вызываем функцию handleSubmit в настраиваемом хуке.
Теперь давайте напишем функцию, которую мы прикрепили к нашей кнопке сохранения, handleSave (). Это та часть, куда мы фактически отправляем наши данные. Я использую Axios для всех вызовов API. Axios - это библиотека для выполнения HTTP-запросов; This - хорошее руководство по его использованию с React.
import { useState } from 'react'; import axios from 'axios'; import { convertToRaw } from 'draft-js'; export default function useSubmit() { const submitPage = async (data) => { const content = JSON.stringify(convertToRaw(data)); return axios.post('/posts', { content }).catch(err => console.log(err)); } return { submitPage } }
Разобьем этот POST-запрос на части:
- Я вызываю встроенный метод Draft.js
getCurrentContent()
в editorState. Этот метод возвращает объектcurrentState
, который содержит текст и все его стили. - Я использую встроенный метод Draft.js
convertToRaw()
, который преобразует состояние содержимого в объект JS, содержащий блоки содержимого. Кроме того, я использую методJSON.stringify()
, который превращает объект JS в строку JSON. Теперь его можно сохранить как строку. - Я настроил свой запрос на аксиомы. Их можно отформатировать несколькими способами; Я предпочитаю использовать этот объектный формат для запросов POST. Я указываю
method
,url
и конечную точку,data
иheaders
. Обратите внимание, что мой объект данных отформатирован следующим образом:
{ content }
Потому что он отражает настройку моего объекта данных в вызове API createNote () в Express:
res.status(201).json({ status: 'success', data: { content: newNote } })
Они должны соответствовать, чтобы данные могли правильно маршрутизироваться!
Давайте получим данные для нашего POST-запроса. Я собираюсь войти в свой редактор Draft.js и написать несколько образцов данных для отправки:
Я собираюсь добавить немного форматирования к этой заметке, чтобы убедиться, что мое форматирование сохраняется, когда я отправляю эти данные, а затем ПОЛУЧАЮ их позже. Я собираюсь добавить жирный текст и маркированный список:
Когда заметка размещена, она также отображается в моей базе данных следующим образом:
content: {"blocks": [ {"key":"4rh99","text":"It's very gray today. I ate cornflakes ","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}, {"key":"fdh6","text":"honey","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"13aee","text":"a banana","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"bb1p5","text":"and peanutbutter ","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"8j2ad","text":"for breakfast. ","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"fjio6","text":"","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"eblll","text":"Valentine's day is this weekend. ","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":0,"length":16,"style":"BOLD"}],"entityRanges":[],"data":{}}],"entityMap":{}}
Это карта блоков, которая очерчивает различные блоки содержимого, похожие на абзацы. Если вы прочитаете это, это немного покажет, как Draft.js стилизует и хранит данные.
2. ПОЛУЧИТЬ данные Draft.js
Отображение данных Draft.js во внешнем интерфейсе не так просто, как выборка данных и их сопоставление с компонентом. Но это не сложно.
Сначала мы извлекаем данные Draft.js из нашей базы данных, используя запрос GET и /posts
route, который мы создали в нашем API ранее.
Это настраиваемая ловушка для ПОЛУЧЕНИЯ сообщений, которая будет использоваться с компонентом PostGallery для отображения сообщений.
›usePosts.js
import { useState } from 'react'; import axios from 'axios'; import { convertToRaw } from 'draft-js'; export default function usePosts() { const [posts, setPosts] = useState(null); const getPosts = async (page, add) => { return axios.get(`/posts/`) .then(res => { const { docs } = res.data.data; setPosts(docs); }).catch(err => console.log(err)); } return { posts, getPosts } }
Этот запрос GET извлекает данные, хранящиеся на маршруте /posts
, который представляет собой все примечания, и устанавливает для этих документов состояние posts
. Но помните, что это содержимое хранится в объекте. В объекте содержимое представляет собой строку JSON, которая содержит блоки содержимого заметки.
В галерее сообщений содержимое должно быть соответствующим образом проанализировано. Мы собираемся отображать сообщения в объекте редактора Draft.js - таком же, который использовался для написания сообщения, но со свойством readOnly
, установленным таким образом, чтобы отображаемое примечание нельзя было редактировать.
Использование редактора для отображения заметки помимо ее написания имеет несколько преимуществ:
- Легче отображать все стили заметок.
- Свойство
readOnly
можно переключить наfalse
, если после отображения сообщение можно редактировать.
›PostGallery.js
import React, { useEffect } from 'react'; import { Editor, EditorState, convertFromRaw } from 'draft-js'; import usePosts from '../hooks/usePosts'; const PostGallery = () => { const { posts, getPosts } = usePosts(); useEffect(() => { getPosts(); }, []); return( <div className="posts"> {pages && pages.map(el => { const contentState = convertFromRaw(JSON.parse(el.content)); const editorState = EditorState.createWithContent(contentState); return( <div style={{paddingTop:'3rem'}}> <Editor editorState={editorState} readOnly={true} /> </div> ) })} </div> ) }; export default PostGallery;
Этот компонент:
- Вызов функции, которая выполняет запрос GET, в настраиваемой ловушке в ловушке
useEffect
. - Использование
el.content
для получения содержимого примечания из объекта примечания иJSON.parse
для преобразования его обратно в объект из его строкового состояния. Затем applyconvertFromRaw
, функция Draft.js, которая преобразует объект с блоками содержимого обратно в читаемый текст. - Инициализация редактора Draft.js и установка этого анализируемого содержимого в качестве начального состояния редактора редактора.
- Установка редактора на
readOnly
, как обсуждалось, чтобы его нельзя было редактировать.
Он будет отображаться во внешнем интерфейсе как текстовый блок (нередактируемый) с сохраненным богатым стилем. Если вы сохраните другие атрибуты, такие как автор сообщения, дата создания и т. Д., Их можно легко изменить, чтобы они также отображались здесь.
Это все, что нужно для POSTing и GETing данных Draft.js.
Резюме
POST
- Получите текущий контент из состояния редактора с помощью
editorState.getCurrentContent()
и сохраните его в переменной. - Преобразуйте текущее состояние в строку с помощью следующих методов:
JSON.stringify(convertToRaw(data));
ПОЛУЧИТЬ
- Отображение данных в редакторе Draft.js, установленном на
readOnly
- Получите сообщение с сервера, а затем преобразуйте его в читаемый контент с помощью этого.
const contentState = convertFromRaw(JSON.parse(el.content)); const editorState = EditorState.createWithContent(contentState);
- Покажите это в редакторе следующим образом:
<Editor editorState={editorState} readOnly={true}