React: How to Inject React Component into Body

React: How to inject React component into body?

If you opt for a one-liner :

ReactDOM.render(
<Root />,
document.body.appendChild(document.createElement("DIV"))
)

Running Example:

class Root extends React.Component {  render() {    return <div>It works!</div>;  }}
ReactDOM.render( <Root />, document.body.appendChild(document.createElement("DIV")))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
<body></body>

How to create a React Modal (which is appended to <body>) with transitions?

At react conf 2015, Ryan Florence demonstrated using portals. Here's how you can create a simple Portal component...

var Portal = React.createClass({
render: () => null,
portalElement: null,
componentDidMount() {
var p = this.props.portalId && document.getElementById(this.props.portalId);
if (!p) {
var p = document.createElement('div');
p.id = this.props.portalId;
document.body.appendChild(p);
}
this.portalElement = p;
this.componentDidUpdate();
},
componentWillUnmount() {
document.body.removeChild(this.portalElement);
},
componentDidUpdate() {
React.render(<div {...this.props}>{this.props.children}</div>, this.portalElement);
}
});

and then everything you can normally do in React you can do inside of the portal...

    <Portal className="DialogGroup">
<ReactCSSTransitionGroup transitionName="Dialog-anim">
{ activeDialog === 1 &&
<div key="0" className="Dialog">
This is an animated dialog
</div> }
</ReactCSSTransitionGroup>
</Portal>
jsbin demo

You can also have a look at Ryan's react-modal, although I haven't actually used it so I don't know how well it works with animation.

How to append or inject React Class Component in a Modal outside React Tree

The way to render a react component outside of react is to call ReactDOM.render, passing in the react element you want to render and the dom element you want to put it in. For sites that are fully done in react, you would typically call this exactly once. But if necessary, you can do it on the fly or multiple times, targetting specific pieces of your dom.

const element = $('#test-123 #modal-body').get(0);
ReactDom.render(<div><Component /></div>, element);

Be aware that React assumes it is the only piece of code modifying the part of the dom tree that you tell it to operate in. So you should avoid making any further changes to the #modal-body element using jquery.

Append react app directly to body in the right way

If your goal is to insert your <App /> component as the first element in the document body, you could remove the two lines that set up the $container variable and append it, and in your last line, use document.body as your second argument, like so:

ReactDOM.render(<App />, document.body);

Based on your code snippet, it looks like you also need a wrapper div, in which case you could implement that within ./components/App.js

Edit: I should also mention that appending directly to the body is discouraged by the creators of react-dom. You will get a console warning if you do this.

Add a class to the HTML <body> tag with React?

TL;DR use document.body.classList.add and document.body.classList.remove

I would have two functions that toggle a piece of state to show/hide the modal within your outer component.

Inside these functions I would use the document.body.classList.add and document.body.classList.remove methods to manipulate the body class dependant on the modal's state like below:

openModal = (event) => {
document.body.classList.add('modal-open');
this.setState({ showModal: true });
}
hideModal = (event) => {
document.body.classList.remove('modal-open');
this.setState({ showModal: false });
}

Dynamically add React components into DIV or another react App

Checkout this implementation. Basically you need to use the useState React Hook to store all the components that you want to add as children of the canvas.

export default function App() {
const [buttonsOnCanvos, setButtonsOnCanvos] = useState([]);
return (
<div className="App">
<Button
event={() => {
setButtonsOnCanvos([...buttonsOnCanvos, <Button />]);
}}
/>
<div className="canvos">{buttonsOnCanvos}</div>
</div>
);
}

Get body content from custom react component

You can destructure the component children from props.

function Item({ value, children }) {
return <div><p>{children}: {value}</p></div>;
}

function Example() {
return (
<div>
<Item value="foo">Foo</Item>
<Item value="bar">Bar</Item>
<Item value="baz">Baz</Item>
</div>
);
};

ReactDOM.render(
<Example />,
document.getElementById("react")
);
p { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Is it possible to inject react context to div outside the root in react (under the body)

As Eric Hasselbring said, portals address this use case:

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

Here's an example, using context:

const ExampleContext = React.createContext(    "default context");
class Example extends React.Component { render() { return ( <ExampleContext.Provider value="context from Example"> <div> This is the parent comnponent. <MyPortal /> </div> </ExampleContext.Provider> ); }}
class MyPortal extends React.Component { static contextType = ExampleContext; render() { return ReactDOM.createPortal( <div>This is "my portal," context stuff is "{this.context}"</div>, document.getElementById("portal") ); }}
ReactDOM.render( <Example />, document.getElementById("root"));
<div id="root"></div><hr><div id="portal"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Trying to use React.DOM to set body styles

Assuming your body tag isn't part of another React component, just change it as usual:

document.body.style.backgroundColor = "green";
//elsewhere..
return (
<div>
Stuff goes here.
</div>
);

It's recommended to put it at componentWillMount method, and cancel it at componentWillUnmount:

componentWillMount: function(){
document.body.style.backgroundColor = "green";
}

componentWillUnmount: function(){
document.body.style.backgroundColor = null;
}


Related Topics



Leave a reply



Submit