Does react element itself has inner text, inner html? - reactjs

Learning react, i see element examples like this,
const element = <Welcome name="Sara" />;
Does it support ?
const element = <Welcome name="Sara">good day </Welcome>;
If so, how to get "good day" while "name" belongs to props ?
Thanks !

The content of the element is exposed through the children prop.
const Welcome = (props) => {
return <div>
<p>Hello {props.name}!</p>
{props.children}
</div>
};
ReactDOM.render(<Welcome name="Sara">good day </Welcome>, document.body);
<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>

React has children prop out of the box, which accepts nested content inside Component
function Welcome (props) {
console.log('props.name', props.name)
console.log('props.children', props.children)
return <h1>{props.name} {props.children}</h1>
}
function App () {
return (
<div>
<Welcome name="Sara">good day </Welcome>
<Welcome name="Sara" />
</div>
);
}
ReactDOM.render(<App />, document.body)
<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>

Related

How to implement a React equivalent of Vue's IS attribute?

I want to be able to implement:
<div is='a' href='https://stackoverflow.com'>go to Stack Overflow</div>
To render into:
<a href='https://stackoverflow.com'>go to Stack Overflow</a>
What would be the most sensible approach to implement it?
There are a number of ways to do that, but here's one of them:
const CustomComponent = (props) => {
const {is, children, ...rest} = props
return React.createElement(is, {...rest}, children)
}
const App = () => {
return (
<CustomComponent
is={'a'}
href={'https://stackoverflow.com'}
>
go to Stack Overflow
</CustomComponent>
)
}
ReactDOM.render(
<App /> ,
document.getElementById('root')
);
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>
More on React.createElement() here.

using state in dangerouslySetInnerHTML react component

I have a string about html builded by react.
I'm trying to implement render this html string through react, and looking for solution to manage state.
below is simple example.
const App = (props) => {
let code = '<b>Will This Work?</b>';
return (
<div dangerouslySetInnerHTML={ {__html: code} }>
</div>
);
}
I want to manage the state of component rendered with dangerouslySetInnerHTML option.
Can i get any ideas about how approach?
What is dangerouslySetInnerHTML?
It is a way to set the children of the component (as text/html).
Can state be used in it?
Yes state can be used with it; However, the innerHTML MUST be vanilla HTML, NOT JSX. An example of this can be seen below:
(click the button to change the state from text to a red div)
The way this is working is because the state can be inserted into a string literal which will then be handled as HTML encoded text.
const App = (props) => {
const [state,setState] = React.useState("something I set with state");
let code = `<b>Will This Work? ${state}</b>`;
return (
<React.Fragment>
<button onClick={()=>{setState("<div style=\"background-color: red; width:50px; height:50px;\"><div>")}}>Click to change state from pure text to an html element</button>
<div dangerouslySetInnerHTML={ {__html: code} }>
</div>
</React.Fragment>
);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.querySelector('.react')
);
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class='react'></div>
Should you do this?
Probably not. There is a reason it is called dangerouslySetHTML and not safelySetInnerHTML.
See more in the React Docs

getting innerHTML from a div after changes through contentEditable in React

thanks for taking the time to look at this.
I am struggling to find out how to make this work specifically in react.
I have used contentEditable to get the div element to be editable and then i have used Refs to make the div reference its innerHTML. But the information does not seem to be put into the state of body.
The ultimate aim is to have it saved in a database, and then loaded to replace the div.
code:
import React, {useState, useRef} from "react";
import "./styles.css";
export default function App() {
let myRef= useRef()
const [body, setBody] = useState("");
let click = () => {
setBody(myRef.innerHTML)
}
return (
<div className="App">
<h1 ref={myRef}>Hello CodeSandbox</h1>
<div></div>
<h1 contentEditable={true}> rewrite me!</h1>
<button onClick={click}> CLICK!</button>
<h1>{body}</h1>
</div>
);
}
sandbox
https://codesandbox.io/s/wispy-glitter-nfym4?file=/src/App.js
Access the innerHTML using myRef.current.innerHTML.
From the docs
When a ref is passed to an element in render, a reference to the node becomes accessible at the current attribute of the ref.
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
function App() {
let myRef = React.useRef();
const [body, setBody] = React.useState("");
let click = () => {
setBody(myRef.current.innerHTML);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div></div>
{/* I think you misassigned your `myRef`, shouldn't it be on this h1? */}
{/* suppressContentEditableWarning=true, to suppress warning */}
<h1 ref={myRef} contentEditable={true} suppressContentEditableWarning={true}> rewrite me!</h1>
<button onClick={click}> CLICK!</button>
<h1>{body}</h1>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
</script>

How to identify React component tags after build in a CRA app?

I would like to create and use this component in React with ES6:
<Menu>
<MenuHeader>Hi</MenuHeader>
<MenuItem>Hello</MenuItem>
<MenuFooter>End</MenuFooter>
</Menu>
I've defined a component to handle this structure:
export class Menu extends React.Component {
render() {
return (
<div ...>
<div ...>
{HOW TO SELECT HEADER?}
</div>
<div ...>
{HOW TO SELECT ITEM?}
</div>
<div ...>
{HOW TO SELECT FOOTER?}
</div>
</div>
)}
}
It's okay to iterate over children and select by type.name while running on the dev server without transpilation:
{ React.Children.map(this.props.children, child => { return child.props.type === 'MenuItem' ? <>{ child }</> : '' } ) }
But it does not work after building it (cause of uglify/minify process).
For example, Semantic UI React handles it well - but it uses interfaces and written in TypeScript so I cannot use it as reference.
And one more thing (ah Steve:): I do not want to use npm eject.
This is normally done by allowing the compound components inside them to render their own children and Menu would just render the children it gets, hence maintaining the order.
You might want to share the state of things happening between the Header, Body and Footer, so we add a ContextProvider to the Menu component, so they can all share common state.
const rootEl = document.getElementById('root');
const { render } = ReactDOM;
const { createContext } = React;
function MenuHeader({ children }) {
return (
<header className="menu-header">
{children}
</header>
)
}
function MenuBody({ children }) {
return (
<div className="menu-body">
{children}
</div>
)
}
const MenuContext = createContext();
Menu.Header = MenuHeader;
Menu.Body = MenuBody;
function Menu({ children }) {
return (
<MenuContext.Provider value={null}>
<div className="menu-wrapper">
{children}
</div>
</MenuContext.Provider>
);
}
function App() {
return (
<Menu>
<Menu.Header>Menu Header</Menu.Header>
<Menu.Body>Menu Body</Menu.Body>
</Menu>
);
}
render(<App />, rootEl);
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root" />
Another common technique used by Frameworks like Ant.Design is to map over the children and add common props to them (although context would be the better solution in my opinion)

Multipe parameters when defining react component as a function

Consider the following code snippet
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
When defining a component as a function, is it possible to pass in arguments that aren't the properties object (such that additional work could be done before rendering)? I tried, and the code failed to render anything on the screen. The changes I tried to make are shown below.
function Welcome(props, same) {
return <h1>Hello, {props.name} and {same}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
Below is a working sample of react code using cdn. Hope it helps :)
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script type="text/babel">
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Johnson" />;
ReactDOM.render(
element,
document.getElementById('root')
);
</script>

Resources