Multipe parameters when defining react component as a function - reactjs

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>

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

Does react element itself has inner text, inner html?

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>

How to add multiple React components to HTML

I wonder if we can add multiple react components into HTML without having the related files usually downloaded with npm, or added to a normal HTML but we add a certain component for a chat app as my attempt here, here is a long example:
<html lang="en">
<head>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<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>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class App extends React.Component{
state={
messages:[
{ }
],
userId:''
}
addMessage=(message)=>{
message.num = Math.random();
message.id=this.state.messages.id;
let messages = [...this.state.messages, message];
this.setState({
messages })
}
addId=(userId)=>{
this.setState({
userId
})
}
render() {
return (
<div className="appContainer">
<User userId={this.addId} />
<TopSection Users={this.state.userId}/>
<Messages userId = {this.state.userId} messages={this.state.messages}/>
<AddMessage addMessage={this.addMessage} />
</div>
);
}
}
}
const Messages = ({messages, userId}) =>{
const messageList= (messages.length)? (messages.slice(1).map(message=>{
return(
<div className="message" key={message.num}>
<span key={userId.num}>{message.content?(userId):(null)}</span>
<p>{message.content}</p>
</div>
)
})) : (null);
return(
<div className="textContainer">
{messageList}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'));
</script>
</body>
</html>
please let me know if there is away to get this to work.
You mean add components to different dom nodes ?
import {render} from 'reactDOM'
import React from 'react'
import AppOne from './appOne'
import AppTwo from './appTwo'
render(<AppOne />, document.getElementById('appOne'));
render(<AppTwo />, document.getElementById('appTwo'));
React v16 has portals as well for adding componnets to differnt parts of the dom tree

React: How to mount all components on page?

I want to be able to mount React components based on the HTML markup of a document rendered by a PHP framework and I can't find a way to achieve this.
Here is the HTML markup of my document:
<html>
<head>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div id="app">
<Foo bar="lorem"></Foo>
<Foo bar="ipsum"></Foo>
<Foo bar="dolor"></Foo>
</div>
<script src="js/index.js"></script>
</body>
</html>
Here is the Foo component implementation (foo.js):
const React = require('react');
class Foo extends React.Component {
render() {
return React.createElement('div', {
className: 'foo'
}, `Hello ${this.props.bar}`);
}
}
module.exports = Foo;
And here is my App implementation (app.js):
const React = require('react');
const ReactDOM = require('react-dom');
require('./foo');
ReactDOM.render(
React.createElement('div'),
document.getElementById('app')
);
module.exports = {};
I'm expecting React to recursively mount every components found inside the #app div but for some reason only the #app div is mounted resulting in the following markup:
<div id="app">
<div data-reactroot=""></div>
</div>
I can't put my fingers on what I am doing wrong here.
So, in you app.js when you are rendering react DOM
ReactDOM.render(
React.createElement('div'),
document.getElementById('app')
);
In this case you are creating a div element and rendering it inside root div with id=app
In order to create multiple foo elements all you have to do is this
const Foo = require('./foo');
ReactDOM.render(
<div>
<Foo bar="lorem"></Foo>
<Foo bar="ipsum"></Foo>
<Foo bar="dolor"></Foo>
</div>
document.getElementById('app')
);
Hope this helps

Resources