React Typerscript How to pass a function to my class from another function file? - react-tsx

I'm new to React Typerscript, and I'm trying to figure out how to pass useModal function from RsvpPage to EventDescriptionPage.
`
import Modal from "./Modal";
import useModal from "./UseModal";
class EventDescriptionPage extends Component<any,any> {
constructor(props:any){
super(props);
}
render(){
return (
<div onClick={this.props.useModal}>
<button className='button' onClick={this.props.toggle}> RSVP </button>
<Modal isOpen={this.props.isOpen} toggle={this.props.toggle}></Modal>
</div>
</header>
</div>
);
}
}
export default EventDescriptionPage;
`
`
import EventDescriptionPage from "./EventDescriptionPage";
import Modal from "./Modal";
import useModal from "./UseModal";
function RsvpPage(){
const { isOpen, toggle } = useModal();
return (
<div>
<EventDescriptionPage/>
</div>
);
}
export default RsvpPage;
`
`
import { useState } from "react";
export default function UseModal() {
const [isOpen, setisOpen] = useState(false);
const toggle = () => {
setisOpen(!isOpen);
};
return {
isOpen,
toggle
};
}
`
`
import React, { ReactNode } from "react";
import "./Modal.css";
interface ModalType {
children?: ReactNode;
isOpen: boolean;
toggle: () => void;
}
export default function Modal(props: ModalType) {
return (
<>
{props.isOpen && (
<div className="modal-overlay" onClick={props.toggle}>
<div onClick={(e) => e.stopPropagation()} className="modal-box">
{props.children}Abaabaabaaba
</div>
</div>
)}
</>
);
}
`
I think my syntax is not right, but I'm not sure how to access useModal() function in RsvpPage.esx file.

Related

How can I mix between a ssr component and a client component in Nextjs 13?

The point is to implement a dynamic SSR component can be re-rendered by a search input.
I solved this by creating a layout.tsx file on my specific router then import children which made me dynamic render ssr component by the client component:
Layout.tsx
import React, { Suspense } from "react";
import Search from "./Search";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="layout">
<Search />
{children}
</div>
);
}
Search.tsx
"use client";
import { FormEvent, useState } from "react";
import { useRouter } from "next/navigation";
export default function Search() {
const [text, setText] = useState<string>("")
const router: any = useRouter();
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setText('')
router.push(`/definition/${text}`)
}
return (
<form onSubmit={handleSubmit} className='search'>
<input onChange={(e) => setText(e.target.value)}
value={text} type="text"
placeholder={"write to search"} />
</form>
);
} );
}

Cannot display data in the table

Problem:
It doesn't work to use " const [data, setData] = useState<IHit[]>([]);" because I get the error "data.map is not a function"
What part am I missing?
Thank you!
import React, { useState, useEffect } from 'react';
import { render } from 'react-dom';
import axios from 'axios';
import './style.css';
import { IHit } from './responseTypes';
function App() {
const [data, setData] = useState<IHit[]>([]);
const [query, setQuery] = useState('react');
useEffect(() => {
let ignore = false;
console.log('useeffect: ', ignore);
async function fetchData() {
const result = await axios(
'https://hn.algolia.com/api/v1/search?query=' + query
);
if (!ignore) setData(result.data);
}
fetchData();
return () => {
ignore = true;
console.log('return: ', ignore);
};
}, [query]);
if (data.length === 0) return <div>Testtest</div>;
return (
<div>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<ul>
{data.map(({ url, objectID, title }: IHit) => (
<a href={url}>
<li key={objectID}>{title}</li>
</a>
))}
</ul>
</div>
);
}
render(<App />, document.getElementById('root'));
https://stackblitz.com/edit/usereducer-typescript-state-uaft7n?file=index.tsx

How to Call API In NextJS Using Redux With SSR?

Need One Help i am trying to call api in nextjs using
redux(Here,SSR is not possible)
and getServerSideProps(Here, SSR is Possible but without redux) in both case API Called Successfully. If i used it individually bot are working well but now i want to merge it both and i have read about next-redux-wrapper but when i am integrate it.
API Called Using GetServerSideProps()
index.js
`
import Product from "./product-cart";
import React from "react";
import styles from "../styles/Product.module.css";
import axios from "axios";
const Home = ({ products, loading }) => {
return (
<>
{loading ? (
<h1>Loading...</h1>
) : (
<>
<div className={styles.banner}>
<p>Welcome to ecommerce!</p>
<h1>FIND AMAZING PRODUCT BELOW</h1>
<a href="#container">
<button>Scroll</button>
</a>
</div>
<h2 className={styles.homeHeading}>Featured Product</h2>
<div className={styles.container} id="container">
{products &&
products.map((products) => (
<Product key={products._id} products={products} />
))}
</div>
</>
)}
</>
);
};
export default Home;
export async function getServerSideProps(context) {
let link = `http://localhost:5000/api/v1/product`;
const { data } = await axios.get(link);
return { props: { products: data.product } };
}
`
API Called Using Redux
_app.js
`
import { Provider } from "react-redux";
import store, { wrapper } from "../redux/store";
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return (
<>
<Provider store={store}>
<Component {...pageProps} />
</Provider>
</>
);
}
// export default wrapper.withRedux(MyApp);
export default MyApp;
`
index.js(GetProduct() Created In Action File)
`
import Product from "./product-cart";
import React from "react";
import styles from "../styles/Product.module.css";
import { clearErrors, getProduct } from "../redux/Actions/ProductAction";
import { useSelector, useDispatch, connect } from "react-redux";
import axios from "axios";
import { wrapper } from "../redux/store";
const Home = ({ products, loading }) => {
const { loading, error, products } = useSelector(
(state) => state.products || {}
);
const dispatch = useDispatch();
React.useEffect(() => {
if (error) {
dispatch(clearErrors());
}
dispatch(getProduct());
}, [dispatch]);
return (
<>
{loading ? (
<h1>Loading...</h1>
) : (
<>
<div className={styles.banner}>
<p>Welcome to ecommerce!</p>
<h1>FIND AMAZING PRODUCT BELOW</h1>
<a href="#container">
<button>Scroll</button>
</a>
</div>
<div suppressHydrationWarning>
{process.browser ? "browser" : "server"}
</div>
<h2 className={styles.homeHeading}>Featured Product</h2>
<div className={styles.container} id="container">
{products &&
products.map((products) => (
<Product key={products._id} products={products} />
))}
</div>
</>
)}
</>
);
};
export default Home;
`
If you need more information let me know
TypeError: makeStore is not a function
enter image description here
Try to Use Next-redux-wrapper but not able to find solution regarding that
_app.js
import { Provider } from "react-redux";
import store, { wrapper } from "../redux/store";
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return (
<>
<Provider store={store}>
<Component {...pageProps} />
</Provider>
</>
);
}
export default wrapper.withRedux(MyApp);
store.js
import {
createStore,
combineReducers,
applyMiddleware,
legacy_createStore,
} from "redux";
import thunk from "redux-thunk";
// import { createStore } from "redux";
import { createWrapper, HYDRATE } from "next-redux-wrapper";
import { composeWithDevTools } from "redux-devtools-extension";
import {
adminProductEDReducer,
AdminProductReducer,
newProductReducer,
newReviewReducer,
productDetailReducer,
productReducer,
} from "./Reducers/ProductReducer";
import {
userReducer,
profileReducer,
forgotPasswordReducer,
allUserReducer,
userDetailsReducer,
} from "./Reducers/UserReducers";
const reducer = combineReducers({
products: productReducer,
productDetails: productDetailReducer,
adminProduct: AdminProductReducer,
newProduct: newProductReducer,
user: userReducer,
profile: profileReducer,
forgotPassword: forgotPasswordReducer,
newReview: newReviewReducer,
EditDelProduct: adminProductEDReducer,
allUser: allUserReducer,
userDetail: userDetailsReducer,
});
// if the value is in cart otherwise it will be blank and we can store cartitems in localstorage
let initialState = {};
const middleware = [thunk];
const store = legacy_createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
// export an assembled wrapper
export const wrapper = createWrapper(store, { debug: true });
export default store;

Dynamic data fetching in dynamic pages (Next.js and Redux Toolkit)

In this dynamic page, we have to fetch different APIs by coming from different routes. I want to dynamically fetch and list not only fetchProducts, but also crops from any data on this page. For example: How should we do this? the code you see is from index.js
File structure:
product/
[category]
[slug].js
index.js
import React, { useEffect } from "react";
import { ProductCard } from "#components/Product/ProductCategory/ProductList";
import { useDispatch, useSelector } from "react-redux";
import { fetchProducts } from "redux/slices/product/productCategorySlice";
import { useRouter } from "next/router";
import Link from "next/link";
const CategoryDetail = () => {
const router = useRouter();
const { category } = router.query;
const productList = useSelector((state) => state.productCategory);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchProducts(category));
}, [dispatch, category]);
return (
<div className="container max-w-full">
<div className="flex flex-row py-24">
<div className="w-80per pl-30">
{productList.loading && console.log("Loading now...")}
{!productList.loading && productList.error
? console.log(productList.error)
: null}
{!productList.loading && productList.productList.data
? (
<div className="grid grid-cols-4 gap-5">
{productList.productList.data.data.map((item) => (
<ProductCard key={item} data={item} modal={false} />
))}
</div>
)
: null}
</div>
</div>
</div>
);
};
export default CategoryDetail;

How to change style just one element that clicked in map React?

I want to scale only one element in the map when clicking on the picture. I read that I have to use an index but I don't know how to do it. I also saw how to do it in inline "onclick" by passing index there. But I want to do it with separated function.
Here is the code :
import './App.css';
import { useSelector, useDispatch } from 'react-redux';
import { useEffect, useState } from 'react';
import { birds, mountains,trees, search } from './features/slices/photoSlice';
function App() {
const url = useSelector((state)=>state.url)
const dispatch = useDispatch()
const [photos, setPhoto] = useState('')
const [scale, setScale] = useState(false)
const [photoindex, setPhotoindex] = useState(0)
useEffect(()=>{
fetch(url).then(res=>res.json()).then(data=>setPhoto(data))
},[url])
const handleSearch = (e) =>{
if(e.key==='Enter'){
e.preventDefault()
dispatch(search(e.target.value))
}
}
const handleClickOnPicture = (e) => {
if(e){
setScale(!scale)
}
}
return (
<div className="App">
// Problem is here below:
{photos?photos.hits.map((photo, index)=>{
return <img className={scale?'m-5 h-80 scale-125':'m-5 h-80'} onClick={handleClickOnPicture} key={photo.webformatURL} src={photo.webformatURL}/>
}):""}
</div>
</div>
</div>
);
}
export default App;
I removed half of the code, so you will see only the problem.
use event.target.classname to add/remove classes
const handleClickOnPicture = (e) => {
if(!e.target.classList.contains('scale-125')){
e.target.classList.add('scale-125')
}
else{
e.target.classList.remove('scale-125')
}
}
<img className='m-5 h-80' onClick={handleClickOnPicture} key={photo.webformatURL} src={photo.webformatURL}/>

Resources