I thought it was simple but looks like I´m doing something wrong
const name = "Mike"
...
<MyComponent
data={
<Picture /> + " " + name
}
/>
const Picture () => return <img src="..." />
const myComponent (props) => return props.data
i´m getting this output
[object Object] Mike
thank you!
You should separate the passing of both items into 2 different props, rather than joining them together (they are both different types - ReactNode, and string). The advantage of doing so is that there will be better type checking, especially if you are using TypeScript or PropTypes.
<MyComponent
data={<Picture />}
name={user.name}
/>
Then in the myComponent itself, you should do this if you are trying to print the name under the Picture.
const myComponent = ({ data, name }) => (
<>
{data}
{name}
</>
);
const Picture = () => <img alt="" src="" />;
const MyComponent = props => props.data;
export default function App() {
return (
const user = ...
<MyComponent
data={
<>
<Picture />
{user.name}
</>
}
/>
);
}
Any value should be passed thru {your value}
{user.name}
In this part of code, you shouldn't use return const MyComponent = props => props.data;
If you wanna return it in classic way write like this:
const MyComponent = props => {
return props.data
};
You can check this example:
Parent Component
import React, {Component, useEffect, useState} from 'react';
import {ChildComp} from "./ChildComp";
import {Hello} from "./Hello";
export class ParentComp extends Component {
render() {
return (
<div>
<ChildComp>
<Hello/>
</ChildComp>
</div>
);
}
}
Child Component
import React, {Component, useEffect, useState} from 'react';
export class ChildComp extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
Hello Component
import React, {Component, useEffect, useState} from 'react';
export class Hello extends Component {
render() {
return (
<div>
<h1>Hello World</h1>
</div>
);
}
}
You can pass a component as a prop. However, look at this line:
<Picture /> + " " + user.name
Since <AnyComponent /> results in a React element, and a React element is internally represented as an object, you're essentially doing this:
{} + " " + user.name
which is why you're seeing [object Object] in your output. What you should do is
function MyComponent({ pictureElement, name }) {
return (
<div>
{pictureElement} {name}
</div>
);
}
Related
I am trying to pass a function on the sectionOne, then call sectionOne from another component but I am getting an error.
Error: Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
import React from 'react';
import {Home} from './home';
export const appTabBar = {
sectionOne: function sectionOne() {
return (
<>
<Home />
</>
);
},
};
import React from 'react';
import PropTypes from 'prop-types';
export const DrawerSection = props => {
const {sectionOne} = props;
return (
<>
<div>{sectionOne}</div>
</>
);
};
DrawerSection.propTypes = {
sectionOne: PropTypes.any,
};
You want to render sectionOne as a React component, and user-defined components must be capitalized. You can either rename sectionOne in the file where it is declared or assign it to a variable in the file where it is used:
export const DrawerSection = props => {
const {sectionOne: SectionOne} = props;
return (
<>
<div><SectionOne /></div>
</>
);
};
I written my code following a udemy course. I'm unable to render the Layout component's content is there anything I missed or any syntax mistakes that needs to be corrected to sort this out ?
const Aux = (props) => {props.children}
export default Aux;
import React,{Component} from 'react'
import Layout from './components/Layout/Layout';
class App extends Component
{
render() {
return (
<div>
<Layout>
<p>Hai.. Is this working ? </p>
</Layout>
</div>
);
}
}
export default App;
import React from 'react';
import Aux from '../../hoc/Auxx';
const layout = (props) =>(
<Aux>
<div>Toolbar,Sidebar,Backdrop</div>
<main>
{props.children}
</main>
</Aux>
);
export default layout;
You problem is that Aux is a blank component.
When you use the syntax const Aux = (props) => {props.children} you actually return nothing!
You see, javascript thinks that { } is the function itself and not return your props.children. Just remove the brackets:
const Aux = (props) => props.children;
I've modified your code as below:
const Aux = (props) => props.children // removed the {} so that it can return the children
export default Aux;
import React,{Component} from 'react'
import Layout from './components/Layout/Layout';
class App extends Component
{
render() {
return (
<div>
<Layout>
<p>Hai.. Is this working ? </p>
</Layout>
</div>
);
}
}
export default App;
import React from 'react';
import Aux from '../../hoc/Auxx';
const Layout = (props) =>( //changed the layout to Layout: it needs to be capitalized
<Aux>
<div>Toolbar,Sidebar,Backdrop</div>
<main>
{props.children}
</main>
</Aux>
);
export default layout;
Is there a cleaner way to do a condition in a react component? Say I have something like this:
<Track>
<ProductLink>
<Image ... />
<Typography ...>{...}</Typography>
<Typography ...>{...}</Typography>
</ProductLink>
</Track>
And with conditions, it would be like this:
{condition ? <Track><ProductLink> : <> }
<Image ... />
<Typography ...>{...}</Typography>
<Typography ...>{...}</Typography>
{condition ? </ProductLink></Track> : </> }
Is there another way of doing the condition?
If condition is met, have the Track and ProductLink component, if not, just display the Fragment component.
I'd recommending hoisting the Track and ProductLink into a reusable component -- that way you'll simplify it to one condition.
For example:
import React from "react";
import PropTypes from "prop-types";
import Track from "./path/to/Track";
import ProductLink from "./path/to/ProductLink";
const TrackProduct = ({ children, isTracked }) => (
isTracked
? <Track>
<ProductLink>
{children}
</ProductLink>
</Track>
: children
);
TrackProduct.proptTypes = {
children: PropTypes.node.isRequired,
isTracked: PropTypes.bool.isRequired
};
export default TrackProduct;
Then import the above reusable component and control it via state:
import React from "react";
import TrackProduct from "./path/to/TrackProduct";
import Image from "./path/to/Image";
import Typography from "./path/to/Typography";
import Button from "./path/to/Button";
class Example extends Component {
state = { isTracked: false };
toggleTrack = () => this.setState(prevState => ({ track: !prevState.isTracked }))
render = () => (
<TrackProduct isTracked={this.state.isTracked}>
<Image ... />
<Typography ...>{...}</Typography>
<Typography ...>{...}</Typography>
<Button onClick={this.toggleTrack}>
{!this.state.isTracked ? "Track" : "Untrack"} Product
</Button>
</TrackProduct>
)
};
export default Example;
If the above doesn't quite work and/or is too repetitive, then you can use a render prop that passes some of its own state and class fields to a child function to be controlled (I prefer this method over wrapper HOCs, since they're easier to test against).
For example:
import React, { Component } from "react";
import PropTypes from "prop-types";
import Track from "./path/to/Track";
import ProductLink from "./path/to/ProductLink";
class TrackProduct extends Component {
state = { isTracked: false };
toggleTrack = () => this.setState(prevState => ({ track: !prevState.isTracked }))
render = () => {
const renderedChildren = this.props.children({
isTracked: this.state.isTracked,
toggleTrack: this.toggleTrack
});
return (
isTracked
? <Track>
<ProductLink>
{renderedChildren}
</ProductLink>
</Track>
: renderedChildren
)
};
};
TrackProduct.proptTypes = {
children: PropTypes.func.isRequired,
};
export default TrackProduct;
Then import the above reusable render prop component and control it via TrackProduct's passed down props (isTracked and toggleTrack):
import React from "react";
import TrackProduct from "./path/to/TrackProduct";
import Image from "./path/to/Image";
import Typography from "./path/to/Typography";
import Button from "./path/to/Button";
const Example = () => (
<TrackProduct>
{({ isTracked, toggleTrack }) => (
<>
<Image ... />
<Typography ...>{...}</Typography>
<Typography ...>{...}</Typography>
<Button onClick={toggleTrack}>
{!isTracked ? "Track" : "Untrack"} Product
</Button>
</>
)}
</TrackProduct>
);
export default Example;
More info about render props can be found in this Phoenix ReactJS conference talk.
I want to change innerHTML of a div, when I click on the button. I don't know why, but instead of getting an error, or getting the expected result it deletes to content and replacing it with "[object Object]".
How can I get it work?
import React from 'react';
import Login from './components/login.js';
import SignIn from './components/signin';
import './App.css';
function App() {
function LoginOnClick(){
document.getElementById("wrapper").innerHTML = <SignIn />;
}
return (
<div className="container" id="wrapper">
<button onClick={LoginOnClick}>Login</button>
<Login />
</div>
);
}
export default App;
You can make use of Hooks (Added n React 16.8).
import React, {useState} from 'react';
import Login from './components/login.js';
import SignIn from './components/signin';
import './App.css';
function App() {
const [signIn, setSignIn] = useState(false);
return (
<div className="container" id="wrapper">
{signIn ? <SignIn /> : <> //This is React Fragments syntax
<button onClick={() => setSignIn(true)}>Login</button>
<Login />
</>
}
</div>
);
}
export default App;
With react you don’t have to set the innerHtml to do this, instead the more typical way is to have internal state in your component and conditionally render your SignIn component based off that. To use state the component either needs to be class or use hooks, classes are more traditional so I changed the component to be a class.
To make a class a react component you need to extend the class with the React.Component, this is because react components have lots of internal behaviours that you need to include with your class for it to be considered a component.
So
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
signIn: false,
};
this.LoginOnClick = () => {
this.setState({ signIn: true });
};
}
render() {
if (this.state.signIn) {
return (
<div className="container">
<SignIn />
</div>
);
}
return (
<div className=“container”>
<button onClick={this.LoginOnClick}>Login</button>
<Login />
</div>
);
}
}
Here is a simple way to do it:
import {useState} from "react";
const App = () => {
const [txt, setTxt] = useState("");
setTxt(<p> 'Lorem ipsum dummy text blabla.' </p>);
return(
<div>
{txt}
</div>
)
}
export default App;
I am trying to develop a webapp using reactjs and i have a issue. After more than 1 day of research, i don't understand how to do.
I want to use a component which are the main layout of my page adding other component to display in it.
In the component Base2, the child props contains another component.
import React from 'react';
import PropTypes from 'prop-types';
import { Link, NavLink } from 'react-router-dom';
const Base2 = (child) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
<child/> // HERE the dynamic component
</div>
);
export default Base2;
The function calling it is :
const TestBase = ({props}) => {
return (<Base child={MyComponent}/>)
};
Moreover MyComponent can be a class declare following 2 methods:
import React from 'react';
import LoginForm from '../components/LoginForm.jsx';
class MyComponent extends React.Component{
constructor(props) {
super(props);
...
}
render() {
return (
<LoginForm
onSubmit={this.processForm}
onChange={this.changeUser}
errors={this.state.errors}
user={this.state.user}
/>
);
}
}
export default LoginPage;
Second method :
import React from 'react';
import { Card, CardTitle } from 'material-ui/Card';
const MyComponent = {
render() {
return (<Card className="container">
<CardTitle title="React Application" subtitle="Home page." />
</Card>);
}
};
export default MyComponent ;
During my tests, only the second method works. The lack of "instance" (something like that i guess) from the second method might be the issue?
How can I develop Base2 component to take these 2 types of component declaration?
Thanks in advance for your help
First pass the component like this:
<Base child={<MyComponent/>}/>
Then render it inside Base2 component by props.child, the way you wrote the Base2 component, child (just the argument name) will have the value of props not directly the component you are passing in props.
Write it like this:
const Base2 = (props) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
{props.child} //here
</div>
);
In the second method seems to be a simple json containing a render method. To create component in your second method which seems to be wrote in es5 you have to use react.createClass({ render ... })
Seek on internet you will find a lot of es5 example
With the help of #Mayank Shukla i found the best way to do.
import React from 'react';
import PropTypes from 'prop-types';
import { Link, NavLink } from 'react-router-dom';
const Base2 = (props) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
{props.child}
</div>
);
export default Base2;
The function calling it is :
const TestBase = (props) => {
return (<Base2 child={<MyComponent/>}/>)
};
First Method:
import React from 'react';
import LoginForm from '../components/LoginForm.jsx';
class MyComponent extends React.Component{
constructor(props) {
super(props);
...
}
render() {
return (
<LoginForm
onSubmit={this.processForm}
onChange={this.changeUser}
errors={this.state.errors}
user={this.state.user}
/>
);
}
}
export default LoginPage;
Second method :
import React from 'react';
import { Card, CardTitle } from 'material-ui/Card';
const MyComponent = (props) =>{
return (<Card className="container">
<CardTitle title="React Application" subtitle="Home page." />
</Card>);
};
export default MyComponent ;