How to properly encapsulate inside a React component? - reactjs

There is a component
return (
<div className={classNames}>
<img
className={[classes["user__avatar"]]}
alt={props.altAvatar}
src={props.srcAvatar}
/>
<h1 className={[classes["user__name"]]}>{props.userName}</h1>
<Button className={[classes["user__logout"]]} onClick={logOut}>
Logout
</Button>
</div>
I initialize it in another component with such data
<UserProfile
className={[classesAppContainer["app__body"]]}
userName={userProfileName}
alt={userProfileName}
src={userProfilePhoto}
/>
The question is, how do I transfer Alt and Src data not from the outside, but encapsulated?

Related

How can I properly bring data from api?

import React from "react";
import noviceImg from "./resources/kull.jpg";
import female1 from "./resources/f1.png";
import female2 from "./resources/f2.png";
import male1 from "./resources/m1.png";
import male2 from "./resources/m2.png";
import kendi from "./resources/kendi.png";
import styles from "./Personel.module.css";
import {
Header,
Subheader,
Content,
kendisi
} from "./components/Personelcomponents";
import { MdBorderColor } from "react-icons/md";
import { pink } from "#material-ui/core/colors";
import Navbar from "../../components/Navbar/Navbar";
import useWindowSize from "../../hooks/useWindowSize";
import Not from "./Not";
import { Container } from "#material-ui/core";
import { connect } from "react-redux";
var DataisLoaded = false;
const mapStateToProps = (state) => ({
kimlikId: state?.account?.principal?.kimlikId,
sonucList: state?.account?.principal?.sonucList,
DataisLoaded: true
});
const Personel = ({ sonucList }) => {
if (!DataisLoaded)
return (
<div>
<h1> Pleses wait some time.... </h1>{" "}
</div>
);
return (
<div className={styles.root}>
<Navbar className={styles.navBar} />
<Not className={styles.not} />
<Content>
<div className={styles.card_k}>
<img alt="" src={kendi} />
<b>
<h4 className={styles.name}>İSİM</h4>
</b>
<p className={styles.cardtext}>
<br />
Baba Adı:
<br />
Yakınlık Derecesi: Kendisi
<br />
<div>
<button_k type="button">Randevu Al</button_k>
</div>
<div></div>
<br />
</p>
</div>
<div className={styles.card_f}>
<img alt="" src={female1} />
<h4 className={styles.name}>İSİM</h4>
<p class="card-text">
Ana Adı:{sonucList.sonucList[0].bireyAd}
<br />
Baba Adı:
<br />
Yakınlık Derecesi:
<br />
<button type="button">Randevu Al</button>
<div></div>
<br />
</p>
</div>
<div className={styles.card_f}>
<img alt="" src={female1} />
<h4 className={styles.name}>İSİM</h4>
<p class="card-text">
Ana Adı:
<br />
Baba Adı:
<br />
Yakınlık Derecesi:
<br />
<button type="button">Randevu Al</button>
<div></div>
<br />
</p>
</div>
<div className={styles.card_m}>
<img alt="" src={male2} />
<h4 className={styles.name}>İSİM</h4>
<p class="card-text">
Ana Adı:
<br />
Baba Adı:
<br />
Yakınlık Derecesi:
<br />
<div>
<button_m type="button">Randevu Al</button_m>
</div>
<div></div>
<br />
</p>
</div>
<div className={styles.characterBox}>
<h2>Sorceress</h2>
<img alt="" src={noviceImg} />
</div>
<div className={styles.characterBox}>
<h2>Sorceress</h2>
<img alt="" src={noviceImg} />
</div>
<div className={styles.characterBox}>
<h2>Sorceress</h2>
<img alt="" src={noviceImg} />
</div>
</Content>
</div>
);
};
export default connect(mapStateToProps)(Personel);
Sorry for the messy code. I'm kinda new to react and js and trying to bring some data from api but I have no idea what I'm doing really. I'm trying to copy other pages in project and they used mapStateProps and somehow I can bring my data (Sonuclist and KimlikId) from there but the problem is it page loaded without data and cause error. (After then it brings data from api and works normally) to prevent that I used if statement and DataisLoaded check but it doesn't return after the first if. Tried using states but apperantly you can do those in class comp only?
I'm trying to copy other pages in project and they used mapStateProps and somehow I can bring my data (Sonuclist and KimlikId) from there but the problem is it page loaded without data and cause error. (After then it brings data from api and works normally) to prevent that I used if statement and DataisLoaded check but it doesn't return after the first if.
First of all, I would suggest using useSelector instead of mapStateToProps.
I have not seen this approach before. mapStateToProps is (was) used in class components. For functional components we have the useSelector hook which does the exact same thing as mapStateToProps (well, without out of the box memoization, but that's out of this context).
It is highly recommended to use the hook, so I suggest you give it a try :)
Now, back to the issue:
I don't see how this can work at any point in time as it looks like you don't use DataisLoaded from your props, it is a completely different variable that has nothing to do with the actual store.
Try deleting var DataisLoaded = false; and do something like:
const Personel = ({ sonucList, DataisLoaded }) => {
Remember that data from your store will only be available this way. Nevertheless I still highly suggest you give useSelector a try.
Hope this helps :)
https://react-redux.js.org/api/hooks#useselector

How to fix unexpected behavior of Next/Link when it is a child of a button?

I am experiencing some issues with next/link when I use it in my app.
I have a reusable component that renders a button. This component is used twice on the page with different urls each time.
When the page is in desktop view, the button works perfectly. I can navigate from one page to another. When I reduce the size of the screen to either tablet or mobile one redirects correctly and the other one does not respond as expected.
To work around the issue I have enclosed the area inside a link so the user can click outside the button area and still be directed to the page but it is not really the experience I want to offer to the user.
I never had this before. Can someone tell me how to fix this or why is it behaving this way, please? thanks.
const Banner = ({
purpose,
imageUrl,
title1,
title2,
desc1,
linkName,
buttonText,
}) => {
return (
<div className="row flex-lg-row-reverse align-items-center g-5 justify-content-center">
<div className=" col-10 col-sm-8 col-lg-6">
<Image
className="d-block img-fluid mx-lg-auto"
src={imageUrl}
width={700}
height={500}
alt="banner"
loader={myLoader}
/>
</div>
<Link href={linkName} passHref>
<div className="col-lg-4 p-3 text-center text-lg-start border-0">
<h1 className="display-6 fw-bold lh-1 mb-3">{purpose}</h1>
<p className="lead">
{title1}
<br /> {title2}
</p>
<p className="lead">{desc1}</p>
<button className="btn link btn-primary btn-xl w-100">
<Link href={linkName} passHref>
<a> {buttonText}</a>
</Link>
</button>
</div>
</Link>
</div>
);
};
export default function Home({ data }) {
const {
results: {
client: { secondhandListing },
},
} = data;
//console.log('index page results',secondhandListing);
return (
<>
<div
data-spy="scroll"
data-bs-target="main-nav"
data-offset="0"
className="scrollspy-example"
tabIndex="0"
>
<Services />
<div className="section d-flex justify-content-center my-5">
<h1 className="my-5" id="#scrollspyHeading2">
Properties
</h1>
</div>
<div className="container-fluid d-flex justify-content-xxl-between align-items-center flex-wrap flex-lg-nowrap">
<div className="section d-flex">
<Banner
purpose="Rent a Home"
title1="Rental Homes for"
title2="Everyone"
desc1="Explore Apartments, Villas, Homes"
desc2="and more"
buttonText="Explore Renting"
linkName="/search?operationType=rent"
imageUrl="https://bayut-production.s3.eu-central-1.amazonaws.com/image/145426814/33973352624c48628e41f2ec460faba4"
/>
</div>
<div className="section d-flex">
<Banner
purpose="Buy a Home"
title1="Find, Buy & Own"
title2="Your Dream Home"
desc1="Explore Apartments, Villas, Homes"
desc2="and more"
buttonText="Explore Buying"
linkName="/search?operationType=sale"
imageUrl="https://bayut-production.s3.eu-central-1.amazonaws.com/image/145426814/33973352624c48628e41f2ec460faba4"
/>
</div>
</div>
<Team />
<Contact />
</div>
</>
);
}
Run the new-link codemod to automatically upgrade previous versions of Next.js to the new <Link> usage:
npx #next/codemod new-link .
This will change <Link><a id="link">Home<a></Link> to <Link id="link">Home</Link>.
Alternatively, you can add the legacyBehavior prop <Link legacyBehavior><a id="link">Home<a></Link>.
<button> and <a> do not allow interactive content to be their content.
That said, you're passing invalid children to your <Link> component and to the <button> element:
<Link href={linkName} passHref>
<div className="col-lg-4 p-3 text-center text-lg-start border-0">
<h1 className="display-6 fw-bold lh-1 mb-3">{purpose}</h1>
<p className="lead">{title1}<br /> {title2}</p>
<p className="lead">{desc1}</p>
{/* Invalid child */}
<button className="btn link btn-primary btn-xl w-100">
{/* Invalid child */}
<Link href={linkName} passHref>
<a> {buttonText}</a>
</Link>
</button>
</div>
</Link>
That may be the reason of why your component is behaving oddly.
PS. Formatting your code helps by making it more readable. :). You can do that by setting ESLint and Prettier up.
You maybe need to add the legacyBehavior as props in the next/link component.
import Link from 'next/link'
function Legacy() {
return (
<Link href="/about" legacyBehavior>
<a>About Us</a>
</Link>
)
}
export default Legacy
docs: https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-tag

How to toggle between two buttons in React and chnange the NAvlink path based on button clicked

I am trying to toggle between two images in react and trying to change the Navlink route based on the path enter image description here
<button className="lessonTypeButton">
<img
src={singleLessonsType}
alt="singleLessonsType"
className="packageOne"
onClick={lessonSelected}
/>
</button>
<br />
<br />
<br />
<button className="lessonTypeButton">
<img
src={packageLessons}
alt="packageLessons"
className="packageTwo"
onClick={lessonSelected}
/>
</button>
you can have href property to have routes that in URL,
<button className="lessonTypeButton">
<img
src={packageLessons}
alt="packageLessons"
className="packageTwo"
onClick={lessonSelected}
href={/packageLessons}
/>
</button>
<button className="lessonTypeButton">
<img
src={singleLessonsType}
alt="singleLessonsType"
className="packageOne"
onClick={lessonSelected}
href={/singleLessonsType}
/>
</button>
or use hooks,
import { useHistory } from "react-router-dom";
then use it in function,
let history = useHistory();
function lessonSelected = ()=>{
history.push("/singleLessonsType");
}
or simply call onclick event directly,
<button className="lessonTypeButton">
<img
src={packageLessons}
alt="packageLessons"
className="packageTwo"
onClick={history.push("/packageLessons");}
/>
</button>
<button className="lessonTypeButton">
<img
src={singleLessonsType}
alt="singleLessonsType"
className="packageOne"
onClick={history.push("/singleLessonsType");}
/>
</button>

Redux with Gatsby - wrapped Provider is not recognized

I keep encountering the error
could not find react-redux context value; please ensure the component is wrapped in a <Provider>
even though I wrapped my root file in the <Provider> already. My suspicion on what might be wrong is that instead of nested components being wrapped in the <Provider> it is a "Link" to the page that is wrapped instead?
My index.tsx file looks like this
<Provider store={reduxStore}>
<Layout>
<title>Home</title>
<div>
<Image
width="100%"
src="./app-promo1.png"
alt="app promo banner 1"
/>
<Image
width="100%"
src="./app-promo2.png"
alt="app promo banner 2"
/>
</div>
</Layout>
</Provider>
My navbar is inside a Header component which is inside the Layout component.
Layout.tsx
<div>
<LayoutWrapper>
<HeaderWrapper>
<div className="d-none d-md-block">
<Header />
</div>
<div className="d-block d-md-none">
<MobileHeader />
</div>
</HeaderWrapper>
<ContentWrapper>{children}</ContentWrapper>
<FooterWrapper>
<Footer />
</FooterWrapper>
</LayoutWrapper>
</div>
Header.tsx
<Wrapper>
<Container>
<NavWrapper>
<Logo>
<AniLink paintDrip hex="#24B2D8" to="/">
<Image src={logoImg} width="220px" alt="Logo" />
</AniLink>
</Logo>
<div className="d-flex flex-row justify-content-center align-items-center">
<AniLink paintDrip to="/shop" hex="#24B2D8">
<NavItem>Shop</NavItem>
</AniLink>
<AniLink paintDrip to="/activation" hex="#24B2D8">
<NavItem>Activation</NavItem>
</AniLink>
<AniLink cover to="/partners" bg="#24B2D8">
<NavItem>Partners</NavItem>
</AniLink>
<AniLink cover to="/support" bg="#24B2D8">
<NavItem>Support</NavItem>
</AniLink>
</div>
<Button
link="/"
text="Log in"
color="blue"
/>
</NavWrapper>
</Container>
</Wrapper>
The pages that I need the Redux/Provider in are all of these links. ie: /shop, /activation, /partner, and /support. But when I navigate from / to /shop it gives me the error.
One thing to note is that I'm using Gatsby and not create-react-app. I am not sure if there is something special that I would have to do on Gatsby or not.
Your providers need to wrap your component across your application, that's why when you change the page the context is lost. To achieve that in Gatsby, you have available the dual (gatsby-browser.js/gatsby-ssr.js) wrappRootElement API:
const React = require("react")
const { Provider } = require("react-redux")
const createStore = require("./src/state/createStore")
const store = createStore()
exports.wrapRootElement = ({ element }) => {
return (
<Provider store={store}>
{element}
</Provider>
)
}
element stands for the root React element built by Gatsby.

What to do if your submit is outside of redux-form

What to do if your submit is outside of form?
Example:
<Root>
<Header>
<Button label={'SAVE'} onClick={this.clickHandler}/> // <-- My handler for save form data
<Button label={'DELETE'} />
</Header>
<Form onSubmit={this.handleSubmit} fields={fieldsList} /> // <-- My form
<Root />
Should I be using getValues?
From v4.2.0 you can add a ref prop to your form component and call submit() on that ref. See example at http://redux-form.com/5.3.1/#/examples/submit-from-parent
clickHandler() {
this.refs.myForm.submit()
}
<Root>
<Header>
<Button label={'SAVE'} onClick={this.clickHandler}/>
<Button label={'DELETE'} />
</Header>
<Form ref="myForm" fields={fieldsList} />
</Root>

Resources