Calling Multiple component in same page in React.js - javascript

I am creating a react main page which is rendering two react component as
render() {
return (
<Header />
<Test />
);
}
Header is having simple static content.In Test I am calling external api using redux on page page load as
componentWillMount() {
if (this.props.onPageLoadTest) {
this.props.onPageLoadTest();
}
}
render() {
const { data } = this.props;
return (
<div>
{
data.map((a) => (
<div key={a.id}>{a.id}
</div>
))
}
</div>
);
}
Using props I am showing content in Test component.Header and Test are working fine when I am rendering them separately.
When I am trying to combine then only Header is showing but Test is not able to fetch data from API.

You can't do things like this:
render() {
return (
<Header />
<Test />
);
}
there can be only one markup in the return of render()
if you want to render the Header and Test together here, you have to wrap them with one markup,like this:
render() {
return (
<div>
<Header />
<Test />
</div>
);
}

Related

Is there a way to conditionally render content using onClick in react JS?

Is there a way to achieve conditionally rendered content below but instead of using {renderAuthButton()} in the return statement, I want to achieve running renderAuthButton() with onCLick instead?
class App extends Component {
// ...
render() {
let {isLoggedIn} = this.state;
const renderAuthButton = () => {
if (isLoggedIn) {
return <button>Logout</button>;
} else {
return <button>Login</button>;
}
}
return (
<div className="App">
<h1>
This is a Demo showing several ways to implement Conditional Rendering in React.
</h1>
{renderAuthButton()}
</div>
);
}
}
I don't really understand your need but to render conditionally, you can do something like that
state = {
show: false,
}
<div className="App">
<button onClick={() => this.setState((prev) => { show: !prev.show })}>Toggle</button>
{this.state.show && <MyComponent />}
</div>
I'm not completely sure what you're trying to do but this is how you would conditionally render content in react:
class App extends React.Component {
constructor(props){
super(props);
this.state = {
show: false
}
this.toggleShow = this.toggleShow.bind(this);
}
toggleShow(){
this.setState({show: ! this.state.show})
}
render(){
return (
<div>
<button onClick={this.toggleShow}>Filter Content</button>
{this.state.show ? (
<p>This content is conditionally shown</p>
) : (
<p>The content is now hidden</p>
)}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById("root"))
<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>
<div id="root"></div>

How to render several div in render with a function inside

I can't figure this out, I tried to use in render but still failed, how to fix this problem?
render() {
return (
{
<div className="ABC">
<a>ABC</a>
</div>
<div className="DEF">
}
{*Some function create inner html content*}
{
</div>
}
I tried to add tag but it seems like still got the error...
The render method can only return a single root node. You can either wrap everything in a single element (such as a <div>), or use react fragments
A common pattern in React is for a component to return multiple elements. Fragments let you group a list of children without adding extra nodes to the DOM.
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}
You will also see the above written in short Syntax as:
render() {
return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
);
}
You need to have a single closing element for JSX. This might help :
function bar(){
return (
<div>
Some other content
</div>
);
function foo(){
return (
<React.Fragment>
<div>
Some Content in here
{ bar() }
</div
</React.Fragment>
);
render(){
return(
{ foo() }
)
}
You will have to use a single div tag. You can do this by
function foo(){
return (
<div> New content here </div>
);
render(){
return(
<div className="ABC">
<a>ABC</a>
{ foo() }
</div>
)
}

React components override inside render

I am new in react.
I try to output two components with react 16+, that starting like this:
function InsuranceInfo(props) {...
// and
function InsuranceCustomerInfo(props) {...
and main component render function look like this
render()
{
return (
<InsuranceInfo args={this.state.orderIfo}/>,
<InsuranceCustomerInfo args={this.state.orderIfo}>
)
}
when i load the page i see only last one.
can any one help please? thank you!
Do not use comma (,) sign between component. Either wrap the returning component in some html element
render()
{
return (
<div>
<InsuranceInfo args={this.state.orderIfo}/>
<InsuranceCustomerInfo args={this.state.orderIfo} />
</div>
)
}
or use React Fragments:
render()
{
return (
<React.Fragment>
<InsuranceInfo args={this.state.orderIfo}/>
<InsuranceCustomerInfo args={this.state.orderIfo} />
</React.Fragment>
)
}
Try this, which use Fragment
render()
{
return (
<>
<InsuranceInfo args={this.state.orderIfo}/>
<InsuranceCustomerInfo args={this.state.orderIfo}>
</>
)
}
Or array
render()
{
return [
<InsuranceInfo key="info" args={this.state.orderIfo}/>,
<InsuranceCustomerInfo key="customer" args={this.state.orderIfo}>
];
}
The proper way to achieve what you want is to use HOC (Higher-Order Components)
Have a look at the documentation here for more details.

Loading Div before render Page (React)

I have an page but it's heavy, and react still spend some seconds to load all components, i would like to put an div with greater z-index to overlap it. The problem:
componentWillMount prints 'test' on console, but do not render the div:
componentWillMount() {
return (
<div className={this.props.classes.modalLoading}>
TESTE
</div>
)
}
note css= 100vw, 100vh, bg: black, color: white
It's possible dismember in another component 'Loader' to use in another places? (console log don't work)
render() {
const { classes } = this.props
return (
<div className={classes.root} ref={'oi'}>
<LayoutCard {...this.props}/>
</div>
)
}
componentDidMount() {
{console.log('teste 3')}
}
Well, that is not how react works :)
It renders the JSX that is returned from the render() method.. the return value of the componentWillMount() is not associated with the render method.
If you want a loader you should set a state on the main component to swap between a return, that returns a loader div and the return that returns your page content. I'm not sure what you mean by 'loading' in react. Maybe any sync ajax stuff? Set a state after it finished.
if(this.state.loaded) {
return <Loader />
} else {
return <Content />
}
If you mean things like fonts, stylesheets and images...
well thats its a duplicate of
Show loading icon before first react app initialization
almost that, thx for the point #FelixGaebler
componentWillMount() {
this.setState({
flag: true,
})
}
render() {
const { classes } = this.props
if (this.state.flag) {
return (
<div className={this.props.classes.modalLoading}>
<span>TEST</span>
</div>
)
}
return (
<div className={classes.root}>
<LayoutCard {...this.props}/>
</div>
)
}
componentDidMount() {
this.setState({
flag: false,
})
}

How to Retrieve and Render Data from Firebase using ID/Key (with React)?

I’m trying to access data from the Firebase server and then proceed to open a view page of the object. My routing is working for sure I think.
The index component I want the clicked post to link from is this:
renderPosts() {
return _.map(this.state.posts, (post, key) => {
return (
<div key={key} className="thumbnail">
<h2>
<Link to="/view/posts/{post}">
{post.title}
</Link>
</h2>
<p>{post.body}</p>
</div>
);
});
}
I tried to link to the post cause I figured it work based on the componentDidMount used to build that function. And I imported the view component into it as well.
The app.js page is as this:
<BrowserRouter>
<div>
<div>
<Nav/>
</div>
<Switch>
<Route path='/' exact component={List}/>
<Route path='/new' component={NewPost}/>
<Route path='/view' component={View}/>
</Switch>
</div>
</BrowserRouter>
</div>
);
}
}
And the view.js page is as follows:
componentWillMount(){
let postRef = database().ref('posts').orderByKey().limitToLast(100);
postRef.on('value', snapshot => {
let post = { title: snapshot.title, id: snapshot.key };
this.setState({ posts: [post].concat(this.state.posts) });
});
console.log(postRef);
}
}
render() {
return (
<div >
</div>
);
}
}
Sorry. It’s a bit bare now cause I removed everything I have tried. I used a couple articles and videos to try to figure it out but nothing worked. The original lifecycle method and constructor I used for the index page however is this:
constructor(props){
super(props);
this.state = {
title: '',
body: '',
posts:{}
};
this.onInputChange = this.onInputChange.bind(this);
this.onHandleSubmit = this.onHandleSubmit.bind(this);
}
and
componentDidMount(){
database.on('value', snapshot => {
this.setState({
posts: snapshot.val()
});
});
}
I’m sorry, I know it is a lot to get through but I thought I should cover everything that might be useful. But to sum up: My issues are how to retrieve the post from the database and then add the key that Firebase automatically makes to the link and thus render it in a new page.
Ps. My database is exported as this
export const database = firebase.database().ref('/posts’);
I don't understand the question but it sounds like the post key contains the value you want for the link. If that's the case then try...
renderPosts(){
return Object.keys(this.state.posts).map((post, index)=>(
<div key={index} className="thumbnail">
<h2>
<Link to={`/view/posts/${post}`}>
{this.state.posts[post].title}
</Link>
</h2>
<p>{this.state.posts[post].body}</p>
</div>
)}
);
then you should just be able to call your renderPosts function in your render method.
render() {
return (
<div >
{renderPosts()}
</div>
);
}
It might take a little while to get the post data if you're calling firebase so only call the render method when the post data shows up.
render() {
return (
<div >
{this.state.posts && renderPosts()}
</div>
);
}

Categories