Rendering multiple classes/objects via React.js? - javascript

In one React file, I have the following:
ReactDOM.render(
<BlogButton />,
document.getElementById('nav-blog--react')
);
ReactDOM.render(
<NavButton />,
document.getElementById('nav-home--react')
);
ReactDOM.render(
<PoweredByButton />,
document.getElementById('nav-powered--react')
);
Only the first render works: the "BlogButton" shows up. The other two, "NavButton" and "PoweredbyButton" don't show. I'm not getting an error in the console either. Is that because you can't have multiple renders in a file? How would I combine all of these then into one render call?

Although I can't explain you WHY your example doesn't work - from what I know and have read in the react documentation the "go-to" method is creating 1 main/wrapper component which contains everything else.
You can see the wrapper component as your new DOM to which you append new elements.
I suggest you to create one wrapping component which gets rendered directly into the DOM. While the other elements are rendered within the wrapper component.
WrapperComponent
...
render(
<div>
<FirstComponent />
<SecondComponent />
</div>
);
ReactDOM.render(
<WrapperComponent />,
document.getElementById('nav-powered--react')
);

Related

React – how to render additional component inside another mounted one?

Just wonder are there any approaches to render component in another component in React.
I render a <Scene /> component like this:
import Scene from './Scene';
ReactDOM.render(<Scene/>, document.getElementById('root'));
And at some point I need to render another component <Building /> (for example on onClick) so that it should be inside <Scene />
At the current I'm trying to do so like this:
import Building from './Building';
ReactDOM.render(<Building/>, document.getElementById('fields'));
And this fields container inside this render() method is a child (pretty deep one) of <Scene />
Yes, it renders, it's located inside #fields in HTML, but if I go to React developer tools I see this:
<Scene></Scene>
<Building></Building>
React just rendering <Building> outside of <Scene> and I need quite the opposite.
Unfortunately, conditional rendering isn't the case.
You should only use one ReactDOM.render(), not multiple. It's common to create 1 component (often named <App />) and in that component you create logic. Basically, you create the whole app in Javascript/ReactJS, and you use that line to "load" it into your html.
export class App extends React.Component{
render(){
// It now returns only one component, but this is where you would put your react router
return(
<Scene />
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
export class Scene extends React.Component{
render(){
return(
<>
<div> Your normal scene here and if you want <Building /></div>
{ orSomeVariableWhichHasToBeTrue && <Building />}
</>
);
}
}
Also, I suggest trying to follow their Basics tutorial, I think you're missing the way React's intended use. Reading the Doc's again might help for some insights.

Issue with React Code "Target container is not a DOM element."

I'm learning react and am getting a particular error.
If I try to get my Login and Register classes into the render function of my index file to output it, I am getting the error:
Target container is not a DOM element.
It works fine if my render just has login OR register, but when I combine them both into the one render function it gives the error, I'm unsure how to fix this.
I've tried removing one or the other to double check that it compiles successfully and it does, but when I add the second class it fails.
The code for my render function in my Index.js file is;
import React from "react";
import { render } from "react-dom";
import Login from "./Login";
import Register from "./Register";
render(
<Login />,
<Register />,
document.getElementById("root")
);
The ouput code for my Login file is;
render() {
return (
<form>
<pre>{JSON.stringify(this.state)}</pre>
<button onClick={ event => this.login(event) }>Login</button>
<pre {...(this.state.message.isEmpty ? "hidden" : "")}>
{this.state.message}
</pre>
</form>
);
}
}
export default Login;
and the output code for register is almost identical to logins except and line with 'Login' is 'register'
I need help trying to find out what the problem is so I can fix it.
In this way, I can get my html file to display both buttons and not show the error
Target container is not a DOM element
Thank you.
ReactDOM.render takes one React Node, so you have to wrap your two nodes into another:
render(
<>
<Login />
<Register />
</>,
document.getElementById("root")
);

Treating child HTML as a string and as HTML in React

I'm trying to create a component that both shows the result of some HTML that includes other components and shows the code itself. Basically, a container that demos the markup and shows what markup was used with child components intact. The problem I'm having is that I can only seem to get the fully rendered HTML to display as code when I want he literal input that hasn't been resolved and still includes any component tags that have been used.
<ParentComponent>
<div></div>
<ChildComponent></ChildComponent>
<div></div>
</ParentComponent>
I'd like the ParentComponent to both fully render all of its children, but also treat all HTML within it as a string, essentially, ideally without maintaining two copies of the children. The rendered version is no problem, that happens naturally, but the string form I can't seem to grab from anywhere, it gets the rendered version where ChildComponent is replaced by what it renders as.
I guess this should work for your use case.
import React from "react";
import ReactDOM from "react-dom";
import jsxToString from 'jsx-to-string';
const ParentComponent = props => (
<div>
{`I'm a ParentComponent`}
{props.children}
</div>
);
const ChildComponent = () => <div>{`I'm a ChildComponent`}</div>;
const getParent = () => <ParentComponent>
<div />
<ChildComponent />
<div />
</ParentComponent>;
function App() {
return (
<div className="App">
{getParent()}
{jsxToString(getParent())}
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Give it a try.

React.js - ReactDOM.render or can you use inline?

I have started development in REACT and have some small queries on how to use it inline.
I have for example the following code snippet.
ReactDOM.render(
<RitualPromoCode url="/Home/ValidatePromoCode" code="Bongo" location="1" package="17" />,
document.getElementById('promo-code')
);
however when using the above using it within my MVC page is annoying...i would like to be able to within the HTML page use the new "tag" inline...e.g.
<RitualPromoCode url="/Home/ValidatePromoCode" code="Bongo" location="1" package="17" />
How do i go about doing this?
On another note..I want to use multiple components in different parts of my page but don't want to write one HUGE component to use them all together. How can i get one component to update / modify the properties of another on the same page?
Thanks
You can call render in one place. Just create some "main" component which will contain all others.
ReactDOM.render(
<App />,
document.getElementById('promo-code')
);
class App extends Component {
render() {
return (
<div>
<RitualPromoCode url="/Home/ValidatePromoCode" code="Bongo" location="1" package="17" />
<SomeOtherComponent />
<MoreComponent />
<MyComponent />
</div>
);
}
}

How to customize nested components?

How to customize nested components?
I'm building React Native app with Redux.
I have three screens in my app that render list of users.
Follower/Following should show FollowButton:
<FollowersContainer>
<UserList onFollow={func} onUnfollow={func} users={[...]}>
<UserCard user={user} onFollow={func} onUnfollow={func}>
<FollowButton onFollow={func} onUnfollow={func} isFollowing={bool} userId={string} />
</UserCard>
</UserList>
</FollowersContainer>
Ask question screen should show AskButton:
<AskQuestionContainer>
<UserList onAsk={func} users={[...]}>
<UserCard user={user} onAsk={func}>
<AskButton onPress={onAsk} />
</UserCard>
</UserList>
</AskQuestionContainer>
Search Results should not show any button
<SearchResultsContainer>
<UserList users={[...]}>
<UserCard user={user} />
</UserList>
</SearchResultsContainer>
As you can see, all three screens uses UserList and UserCard components.
Currently UserList and UserCard needs to know about onFollow onUnfollow and onAsk actions and how to pass them around.
This can get complicated and not very flexible.
Ideally I want to do something like:
<UserList
rowComponent={
<UserCard button={<FollowButton />} />
}
/>
But how do I pass the actions from the top level component into the actual button? and How do I know which actions to pass?
I could use connect on the actual buttons to pass them the actions directly but I prefer these components stay pure and flexible.
Any suggestion on how to solve it in a clean way?
Thanks,
Ran.
You can pass components as a prop.
render() {
var passedButton = (<FollowButtton />);
var row = (<UserCard button={passedButton} />);
return (
<UserList rowComponent={row}/>
);
};

Categories

Resources