Should I hardcode data or use props in React? - javascript

I am new to React and was wondering if we have to use hardcode data like this:
import React from "react";
import "../src/App.css";
const header = props => {
return (
<header>
<h1>Content Manager</h1>
</header>
);
};
export default header;
import React, { Component } from "react";
import Header from "../src/header";
class App extends Component {
render() {
return (
<div>
<Header />
</div>
);
}
}
export default App;
As you can see the code above, I just put "Content Manager" inside h1 as a usual content just like we do in HTML. Or do I need to use props instead of hardcoding:
import React from "react";
import "../src/App.css";
const header = props => {
return (
<header>
<h1>{props.title}</h1>
</header>
);
};
export default header;
import React, { Component } from "react";
import Header from "../src/header";
class App extends Component {
render() {
return (
<div>
<Header title={"Content Manager"} />
</div>
);
}
}
export default App;
Guys if something is not clear please let me know

Basically If you want to reuse a component you should be using props.
Example:
When you need same header component for 3 places saying "Welcome","Hello" and "Hi" and have hard coded you will result in writing 3 header components with your heading as "Welcome","Hello" and "Hi".
something like this:
const HiHeader = props => {
return (
<header>
<h1>Hi</h1>
</header>
);
};
export default HiHeader;
const HelloHeader = props => {
return (
<header>
<h1>Hello</h1>
</header>
);
};
export default HelloHeader;
const WelcomeHeader = props => {
return (
<header>
<h1>Welcome</h1>
</header>
);
};
export default WelcomeHeader;
and you use them as
<HiHeader/>
<HelloHeader/>
<WelcomeHeader/>
in case, if you use props you can write a single header and pass different props.
example :
const header = props => {
return (
<header>
<h1>{props.title}</h1>
</header>
);
};
export default header;
import Header from './header.js'
<Header title="Hi"/>
<Header title="Hello"/>
<Header title="Welcome"/>

If your header component going to be reused to display different headers pass in the text as a prop. Else, if you are dead sure that this is gonna be used only once, hard coding is fine.
Cheers,

Never hardcoding, it's the evil!

Related

Passing props in React from one file to another

In the below code I want to pass name from Person.js to App.js as prop.But I can't understand how to do it.If you can please explain me how to do that.
App.js
import { useState,useEffect } from 'react';
// import Person from './Person'
function App(props) {
const [greet, setGreeet] = useState("");
return (
<div className="App">
<h1> Good {greet} </h1>
</div>
);
}
export default App;
Person.js
import React from 'react';
import App from './App'
export default function Person (){
const name="Jenifer"
return(
<div></div>
);
}
passing name as prop from person.js(Parent Component) to App.js(Child Component)
Person.js
import React from 'react';
import App from './App'
export default function Person (){
const name="Jenifer"
return(
<div>
<App name={name}/>
</div>
);
}
App.js
import { useState,useEffect } from 'react';
// import Person from './Person'
function App(props) {
const [greet, setGreeet] = useState("");
return (
<div className="App">
<h1> Good Morning {props.name} </h1> // Good Morning Jenifer
</div>
);
}
export default App;
checkout this blog post Passing props between components
I think you are asking for how to pass data from child to parent.
You have to pass a method from App to Person.
And call the method from Person component.
Also please see the docs
https://reactjs.org/docs/lifting-state-up.html
function Person (props){
const {setNameToApp} = props;
const name = "Jennifer";
// this useEffect is called when the component mounts for the first time
React.useEffect(()=>{
setNameToApp(name);
},[])
// I have also shown how to use button to change the greet state in the app.
return (
<div>
<button onClick={()=>{setNameToApp("name when I pressbutton")}}> Set Name </button>
</div>)
}
function App(props) {
const [greet, setGreet] = React.useState("");
// pass setGreet function to components which can call this and change the state of the greet
return (
<div>
<h1> Good {greet} </h1>
<Person setNameToApp = {setGreet} />
</div>
);
}
Finally I found the reason for this.This happened because I tried to pass data from my child class to parent class.It is impossible to do so.

ReactJS is not rendering children

this is my simple home.js code. None relevant code has been removed.
import Banner from '../components/Banner'
export default function Home() {
return (
<Hero>
<Banner title="luxurious rooms" subtitle="delux rooms starting at $299">
<Link to="/rooms" className="btn-primary">
Our rooms
</Link>
</Banner>
</Hero>
and this my banner.js
import React from 'react'
export default function Banner({childern,title,subtitle}) {
return (
<div className="banner">
<h1>{title}</h1>
<div />>
<p>{subtitle}</p>
{childern}
</div>
)
}
I don't understand why it is not rendering.
In the bedg I contd see <banner>. tag inside of hero.
How can I solve this issue?
Ok, I created a pen for this, but it's not saving so I'll add the code here. It looks like you are taking a difficult approach for a relatively easy concept. When you pass props to a component, you access them within that component using this.props.nameOfProp. You don't need to pass link as a child, just add Link inside the child component, and pass the info you need for the Link as props.
EDIT: Here's a working example https://codesandbox.io/embed/elegant-fast-m52bt
import React from "react";
import ReactDOM from "react-dom";
import Banner from "./Banner";
import { BrowserRouter as Router } from "react-router-dom";
class App extends React.Component {
render() {
return (
<div>
<Banner
title={"luxurious rooms"}
subtitle={"delux rooms starting at $299"}
path={"/rooms"}
classList={"btn-primary"}
/>
</div>
);
}
}
ReactDOM.render(
<Router>
<App />
</Router>,
document.querySelector("#app")
);
Then your banner should look something like this:
import React from "react";
import { Link } from "react-router-dom";
class Banner extends React.Component {
render() {
return (
<div className="banner">
<h1>{this.props.title}</h1>
<p>{this.props.subtitle}</p>
<Link
to={this.props.path}
className={this.props.classList}
>
Link Text (could also be a prop)
</Link>
</div>
);
}
}
export default Banner;

How can I access props passed to React.Component

I want to get some props made in the root layer of my react app:
import React from 'react'
import App, { Container } from 'next/app'
export default class MyApp extends App {
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
state = {
language: "pl"
};
render () {
const { Component, pageProps } = this.props
return (
<Container>
<Component lang={this.state.language} />
</Container>
)
}
}
so every new React.Component created should inherit those props. But I'm not sure how I can get them. Let's say I have another component which is <Nav/>.
Shouldn't I be able to get it via props.lang inside Nav.
When I try it says lang undefined.
I would suggest moving language to the React Context API
So this way you create a context
// context.js
import React from 'react';
export const LangContext = React.createContext('pl');
and provide it inside _app.js
// app.js
import React from 'react';
import App, { Container } from 'next/app';
import { LangContext } from '../context';
export default class MyApp extends App {
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
}
state = {
language: 'EN'
};
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<LangContext.Provider value={this.state.language}>
<Component {...pageProps} />
</LangContext.Provider>
</Container>
);
}
}
and whenever you need to access language value you dont need to pass it anymore. It will be available on LangContext. Example usage
// Nav.js
import Link from 'next/link';
import { LangContext } from '../context';
function Nav() {
return (
<LangContext.Consumer>
{lang => {
return (
<div className="site-nav">
<Link href="/">
<a>index</a>
</Link>
<Link href="/about">
<a>about</a>
</Link>
language = {lang}
</div>
);
}}
</LangContext.Consumer>
);
}
export default Nav;
This helps to solve the issue of passing lang props to pages and then to some specific components like Nav. Just wrap a component into a <LangContext.Consumer> if you need it.
Example index.js page
// index.js
import Nav from '../components/Nav';
export default () => (
<div>
<Nav />
<hr />
Welcome to index.js!
</div>
);
** One note: as far as I see you can only use <SomeContext.Provider> inside _app.js
I'm seeing a couple problems in your code example.
First, props are a property on your component, they should be accessed via this.props.
Here is a basic example of passing props to a child component:
import React, { Component } from 'react';
class App extends Component {
render() {
const greeting = 'Welcome to React';
return (
<div>
<Greeting greeting={greeting} />
</div>
);
}
}
class Greeting extends Component {
render() {
return <h1>{this.props.greeting}</h1>;
}
}
export default App;
Using the code sample above, it would seem that your mistake was to use return <h1>{props.greeting}</h1>; instead of return <h1>{this.props.greeting}</h1>;
Second, it would appear that your component setup is a little off. I would expect your component declaration to look something like this:
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
In your code sample, there's no constructor function and state doesn't appear to be set as a property of your component.
Inside of the example <Nav/> component, you must specify at least one argument in the component's function if you wish to access this.props. For example:
const Nav = (props) => ( <div> {this.props.lang} </div> )
Hope this helps!
Summary of my comments above:
Did you try props.lang, or, this.props.lang?
Because you need this.props.lang to access the property.
Hrm, just took a quick peek at my own code -- the initial state is set in constructor(props), and is defined like super(); this.state = (somestate);.
Because you need to set the state in the constructor of classes.

cannot diplay the json data on browser

i have testdata.json file which contains json data, when i try to execute the code below i am getting an error as "A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object". what should i do now?
this is contestpreview.js file:
import React from 'react';
const ContestPreview = (contest) => {
<div className = "contestPreview">
<div>
{contest.categoryName}
</div>
<div>
{contest.contestName}
</div>
</div>
};
export default ContestPreview;
This my app.js file:
import React from 'react';
import Header from './Header';
import ContestPreview from './ContestPreview';
class App extends React.Component {
state= { test : 7};
render(){
return(<div>
<div>
<Header message = "Naming contests"/>
</div>
<div>
<ContestPreview {...this.props.contests}/>
</div>
</div>
);
}
};
export default App;
This is my index.js file:
import React from'react';
import ReactDom from 'react-dom';
import data from './testData';
console.log(data);
import App from './components/App';
ReactDom.render(
<App contest = {data.contest}/>,
document.getElementById('root')
);
Your ContentPreview component doesn't return a React Component. It's a small error on your part, but you can fix this by either adding a return statement, or by replacing your curly-braces with parenthesis.
Like so:
const ContestPreview = (contest) => (
<div className = "contestPreview">
<div>
{contest.categoryName}
</div>
<div>
{contest.contestName}
</div>
</div>
);
export default ContestPreview;
or
const ContestPreview = (contest) => {
return (
<div className = "contestPreview">
<div>
{contest.categoryName}
</div>
<div>
{contest.contestName}
</div>
</div>
);
};
export default ContestPreview;
The latter allows you to add some application logic before the return, if you want (though discouraged).
Since you're using a stateless functional component, you may find my previous answer on the pros/cons of these interesting.
Good luck!

React stateless component not working

This is my code:
import React, { Component } from 'react'
import { BackButton } from 'components/button'
class LandingHeader extends Component {
render() {
const back = (props) => <BackButton forcedBackUrl={props.back.forcedBackUrl} />
return (
<div>
{back}
{this.props.children}
</div>
)
}
}
export default LandingHeader
If i put the <BackButton> component directly it works but if I use a stateless component and return it inside this one it wont. What im missing?
Im following the official documentation (https://facebook.github.io/react/docs/reusable-components.html) and I can't see whats wrong. Thanks.
Looking at the facebook documentation that you provided they give the example of :
const HelloMessage = (props) => <div>Hello {props.name}</div>;
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
and not just returning {HelloMessage}
therefore replace
{back}
with
<Back />
and you should be good to go
You've declared a ReactClass but you aren't rendering it - you have to turn it into a ReactElement:
const Back = (props) => <BackButton forcedBackUrl={props.forcedBackUrl} />
return (
<div>
<Back {...this.props.back} />
{this.props.children}
</div>
);
You need to inject the props into the component
import React, { Component } from 'react'
import { BackButton } from 'components/button'
class LandingHeader extends Component {
render() {
const back = (props) => <BackButton forcedBackUrl={props.back.forcedBackUrl} />
return (
<div>
{back(this.props)}
{this.props.children}
</div>
)
}
}

Categories