Draft.js and stateToHTML, how to render output html in react component? - javascript

I've got my Draft js editor working fine, it saves to my database, using convertToRaw(editorState1.getCurrentContent()), and I am getting it back and converting it to HTML using draft-js-export-html and stateToHTML(convertFromRaw(dbContent.content.text01)).
So far so good... but now I have raw HTML that I want to display in my react component, and here comes the trouble.
Just rendering it with {props.text01} outputs it as a string and turns into <p>adfasfadfs</p> as text.
Obviously I want it to render as HTML. How do I do that?
I have looked at dangerouslySetInnerHTML but I would prefer not having ANOTHER plugin just to get my Draft js working the way I want it to.
Am I going at it the wrong way, or is dangerouslySetInnerHTML the only way to do it?

As described in this answer, React will escape HTML by default (that's why it's just rendered as a string). But you can force the rendering by using the dangerouslySetInnerHTML property. You'd just have to take potential XSS attacks into consideration.
If Draft is already installed, another way to just simply render the content is to use the readOnly prop on the DraftEditor.

you can use this npm module.
link is link
npm install --save html-to-react
Examples
Simple
The following example parses each node and its attributes and returns a tree of React elements.
var ReactDOMServer = require('react-dom/server');
var HtmlToReactParser = require('html-to-react').Parser;
var htmlInput = '<div><h1>Title</h1><p>A paragraph</p></div>';
var htmlToReactParser = new HtmlToReactParser();
var reactElement = htmlToReactParser.parse(htmlInput);
var reactHtml = ReactDOMServer.renderToStaticMarkup(reactElement);
assert.equal(reactHtml, htmlInput); // true

Related

Send React component's HTML to server

So I have a react component, <ReviewScreen />. It takes in some props, styles them, and presents them. I need to convert this component into HTML, and send it to my backend so that I can generate a PDF on my server.
I tried:
import { renderToStaticMarkup } from 'react-dom/server';
import ReviewScreen from '../somePath';
const html = renderToStaticMarkup(ReviewScreen)
// ... send the html variable to backend using some HTTP library
Problem: the html variable is always empty. My question is: a) is this a 'good' way of doing what I'm trying to achieve? b) is there a better method?
UPDATE: Changing to <ReviewScreen /> actually gets a response. However, I forgot to mention that this component also talks to my Redux store which results in an Invariant Violation: Could not find “store” error.
renderToStaticMarkup takes in an element, not the component type - you'd need to do this:
const html = renderToStaticMarkup(<ReviewScreen />)
Or, without JSX:
const html = renderToStaticMarkup(React.createElement(ReviewScreen))
That said, I think you would be better off generating the HTML on the server instead - rendering arbitary markup sent from the client seems like it could get messy.
You should be doing this:
const html = renderToStaticMarkup(<ReviewScreen />)
Not:
const html = renderToStaticMarkup(ReviewScreen)

Ace editor. Set current edits state as base

I'm using ace editor wrapped by react-ace for my project.
How can I destroy all undo/redo history in certain moment when I need it?
I've tried this.aceRef.editor.destroy(); (just react ref bound with editor), but unfortunately it doesn't play well in some circumstances.
So, I just need to clean undo/redo session/history or something like that.
Any solution?
Ace editor actually has this reset method with UndoManager.
Then you need to assign temporary stored undomanager as base.
It could be done smth like that:
const { editor } = this.aceRef;
const session = editor.getSession();
const undoManager = session.getUndoManager();
undoManager.reset();
session.setUndoManager(undoManager);

How do I get an attribute of an element nested in a React component using Jest and/or Enzyme?

I want to test to see whether an image has properly loaded in a React app. I have decided to check the src attribute of the img element nested within the React component. I want to use the Jest testing framework and, if needed, the Enzyme testing utility.
By digging through the Object.keys of a shallow React test component, I was able to come up with the following solution. The line I'm uncertain about is indicated with the asterisks.
import React from 'react';
import {shallow} from 'enzyme';
import App from './App';
it('should have the logo image', () => {
const app = shallow(<App />);
const img = app.find('img');
const src = img.node.props.src; // ******
expect(src).toBe('logo.svg');
});
This solution does work but it seems a little convoluted (it requires a property of a property of a property of a wrapper) and seems somewhat obscure (I can't easily find clear instructions for this online). So, is this the correct/simplest way to do this?
If so, where is the documentation?
If not, how else should/could I be doing this? e.g. Is there some ready-made getAttribute or retrieveProp method, etc. in Enzyme? Is there a better way of doing this using something else instead of Enzyme, e.g. react-addons-test-utils?
This question about React element attributes doesn't seem to quite answer it for me even though the poster there also indicates having a hard time finding documentation about asserting a rendered attribute value. A number of other questions (e.g. here, here and here) deal with React/Jest/Enzyme but don't deal with retrieving attribute values.
After some digging, I found the following. The indicated line in the question:
const src = img.node.props.src;
can be simplified to the following:
const src = img.prop('src');
The documentation can be found here.
If someone knows of a non-Enzyme way of doing this, I'd still be interested in hearing about it.
For me, it worked as below
expect(companySelect.find('input').props()["disabled"]).toBe(true)
props() returns an object having all the attributes of the selector and then it can be browsed as an object.
Hope this helps too....
https://airbnb.io/enzyme/docs/api/ReactWrapper/props.html
The #testing-library/jest-dom library provides a custom matcher toHaveAttribute. After extending expect clause
import '#testing-library/jest-dom/extend-expect'
we can assert like
const rect = document.querySelector('[data-testid="my-rect"]')
expect(rect).toHaveAttribute('width', '256')
With React Test Utilities:
it('should have the logo image', () =>
const app = TestUtils.renderIntoDocument(<App/>);
var image = TestUtils.findRenderedDOMComponentWithTag(app, 'img');
expect(image.getDOMNode().getAttribute('src')).toEqual('logo.svg');
});
Enzyme tests looks much cleaner.
For me this worked
expect(component.find('button').props().disabled).toBeTruthy();
.node is not working After some hard work, I found the following is 100% related to answer for above question
const src = img.getElement().props.src;

Re-transpile JSX on the fly in a reactjs app

Is it possible to access and modify the JSX used to create a React class and re-transpile it on the fly. For example, if you had the following:
var Item = React.createClass({
render: function () {
return <div>Hello</div>
}
}
How could we: access the raw JSX, modify it to return something else, then transpile so the changes could be seen?
YES I understand this could be extremely dangerous.
It's probably easier to compile the JSX to JS first, and then use something like esprima to make the changes you need on the AST esprima gives you. Then pretty print it to JS again.
But I have to ask what your use case is, because it doesn't seem like the very best of ideas.

How to output text in ReactJS without wrapping it in span

In my ReactJS-based application I do:
var _ = React.DOM;
_.span(null, 'some text', _.select(null, ...));
The problem is: 'some text' is wrapped in additional span element in the DOM. Is there any way to avoid this behavior and just output raw text?
To be clear: I want to output
<span>some text<select>...</select></span>
not
<span><span>some text</span><select>...</select></span>
Update: This is now "fixed" in React v15 (2016-04-06) – now comment nodes are added around each piece of text, but it is no longer wrapped in a <span> tag.
We received some amazing contributions from the community in this release, and we would like to highlight this pull request by Michael Wiencek in particular. Thanks to Michael’s work, React 15 no longer emits extra <span> nodes around the text, making the DOM output much cleaner. This was a longstanding annoyance for React users so it’s exciting to accept this as an outside contribution.
Full release notes.
This is currently a technical limitation of React; it wraps any floating text nodes in a span so that it can assign it an ID and refer back to it later. In a future version of React hopefully we can remove this restriction.
You can hard code the html as a last resort.
<option value={value} dangerouslySetInnerHTML={{__html: value}}></option>
Well.. If you're hell bent on doing this, and accept the limitation that you cannot access props or state, you could do this:
var Component = React.createClass({
displayName:"Statics",
statics: {
customRender: function(foo) {
return React.renderToStaticMarkup(<div
dangerouslySetInnerHTML={{__html: foo.bar }}/>);
}
},
render: function () {
return <div dangerouslySetInnerHTML={{__html:
<Component.customRender bar="<h1>This is rendered
with renderToStaticMarkup</h1>" />}} />
}
});
renderToStaticMarkup will not insert any spans or react-dataid, and is meant for static server rendering. It's probably not a great idea to do this, but there you go.
renderToStaticMarkup
Similar to renderToString, except this doesn't create extra DOM
attributes such as data-react-id, that React uses internally. This is
useful if you want to use React as a simple static page generator, as
stripping away the extra attributes can save lots of bytes.
Check the result at: http://learnreact.robbestad.com/#/static
I Changed the version of react and react-dom and worked perfect
"react": "^15.0.1",
"react-dom": "^15.0.1"

Categories

Resources