How can I properly bring data from api? - reactjs

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

Related

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

Is there any way to center this element to screen?

I am starting out using Tailwind with React and I am stuck on this. I tried various methods but still I am stuck. Here is the code and view snippet.
import { Navbar, Welcome, Footer, Services, Transactions } from "./components";
const App = () => {
return (
<div className="min-h-screen">
<div className="h-14 bg-gradient-to-r from-purple-500 to-red-500 border-double rounded-b-3xl border-b-8 w-5/6">
<Welcome />
</div>
<div className="h-14 bg-gradient-to-b from-blue-500 to-green-500 rounded-lg w-1/2 flex justify-center ">
<Services />
</div>
<Transactions />
<Footer />
</div>
);
}
export default App;
Have you try adding mx-auto class to your gradient divs? If that doesn't work you could also try text-center in your main div.

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.

How do I change text on the button for npm package react-microsoft-login?

I'm trying to build a login/register page that will allow multiple users to login/register with multiple login providers such as Microsoft, Google, Instragram etc.
I managed to figure out how to do it with Google and Instagram 3rd party npm packages however, with the Microsoft Login button, there is no option to change the text at all? Is this possible? I want to change it from "Sign in with Microsoft" to "Log in with Microsoft" and "Register with Microsoft" I have my own functionality to handle oAuth registration process.
Here is my code I'll only show the portion that I cannot figure out. In addition, this is the link that shows what props are available for the package.
Microsoft Login npm package doc
import React from 'react';
import { useDispatch } from 'react-redux';
import MicrosoftLogin from 'react-microsoft-login';
import { Link, useHistory } from 'react-router-dom';
import * as actions from 'redux/actions';
const microsoftResponse = (err, response) => {
console.log('err = ', err);
console.log('response successful', response);
};
const RegisterPage = () => {
const dispatch = useDispatch();
const history = useHistory();
return (
<Page title={'Register'}>
<div className={'loginContainer shadow-lg bg-white rounded'}>
<div className={'loginWrapper'}>
<div className={'row'}>
<div className={'col-md-6'}>
<div className={'wrapperOverlay px-4'}>
<h1 className={'text-center'} style={{ borderBottom: '4px solid #ff0000', color: '#ff0000', padding: '20px 0' }}><strong>Register</strong></h1>
<div className={'providers text-center'}>
<ButtonRow id={'loginProvider'}>
<MicrosoftLogin
clientId={xxxxxxxxx}
authCallback={microsoftResponse}
redirectUri={xxxxxxxxx}
/>
</ButtonRow>
</div>
<div className={'separator py-3'}>Or create a new local account</div>
<div className={'formContainer'}>
<Form
enableReinitialize
form={'exampleFormName'}
onSubmit={(values) => alert(JSON.stringify(values, null, 2))}
>
<FieldInput name={'email'} label={'Email'} type={'email'} placeholder={'Email Address'} />
<FieldInput name={'password'} label={'Password'} type={'password'} placeholder={'Password'} />
<FieldInput name={'confirmpassword'} label={'Confirm Password'} type={'password'} placeholder={'Confirm Password'} />
<div className={'resendConfirmation pb-3'}>
<Link to={'/resendemailConfirmation'}>Resend email confirmation</Link>
</div>
<Button className={'w-100 text-center'} type={'submit'} variant={'primary'} text={'Register'} style={{ fontSize: '20px' }} />
<div className={'form-group text-right'}>
<div className={'registerButton pt-3'}>
<span>Already have an Account?</span>
<Link to={'/login'}>
<span id={'question'}>Log In</span>
</Link>
</div>
</div>
</Form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</Page>
);
};
export default RegisterPage;
You can't change text "as it is", because for a button used SVG image. But as workaround, you can pass your custom button by a children prop, with any text that you want.
<MicrosoftLogin clientId={clientId} authCallback={loginHandler}>
<button>Log in with Microsoft</button>
</MicrosoftLogin>
Few things to keep in mind:
you need to do styling for custom button from scratch
button styles should be based on Official Microsoft brand design

How to properly encapsulate inside a React component?

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?

Resources