ReactJS: Change html/jsx element dynamically - reactjs

I wanna change my JSX element tag dynamically but the remaining attributes stay the same.
Let's say I have something like this:-
import React, { useState } from 'react'
import classNames from 'classnames'
import { makeStyles } from '#material-ui/core/styles'
import DesktopWindowsIcon from '#material-ui/icons/DesktopWindows'
import DnsIcon from '#material-ui/icons/Dns'
import StorageIcon from '#material-ui/icons/Storage'
import CloudIcon from '#material-ui/icons/Cloud'
export const try = () => {
const classes = useStyles()
const [changeIconColor, setChangeIconColor] = useState('')
const icons = [
{ id: 0, icon: <DesktopWindowIcon /> },
{ id: 1, icon: <DnsIcon /> },
{ id: 2, icon: <StorageIcon /> },
{ id: 3, icon: <CloudIcon /> },
]
return (
<>
{icons.maps(icon => (
<>
{/* this will work */}
{icon.icon}
</>
))}
</>
)
}
const useStyles = makeStyles((theme) => ({
icon: {
width: 100,
height: 100,
marginBottom: 12,
},
iconMouseHover: {
color: theme.palette.secondary.main
}
}))
But what I wanna do is something like this:-
import React, { useState } from 'react'
import classNames from 'classnames'
import { makeStyles } from '#material-ui/core/styles'
import DesktopWindowsIcon from '#material-ui/icons/DesktopWindows'
import DnsIcon from '#material-ui/icons/Dns'
import StorageIcon from '#material-ui/icons/Storage'
import CloudIcon from '#material-ui/icons/Cloud'
export const try = () => {
const classes = useStyles()
const [changeIconColor, setChangeIconColor] = useState('')
const icons = [
{ id: 0, icon: <DesktopWindowsIcon key={icon.id} className={changeIconColor === icon.id ? classNames(classes.icon, classes.iconMouseHover) : classes.icon} /> },
{ id: 1, icon: <DnsIcon key={icon.id} className={changeIconColor === icon.id ? classNames(classes.icon, classes.iconMouseHover) : classes.icon} /> },
{ id: 2, icon: <StorageIcon key={icon.id} className={changeIconColor === icon.id ? classNames(classes.icon, classes.iconMouseHover) : classes.icon} /> },
{ id: 3, icon: <CloudIcon key={icon.id} className={changeIconColor === icon.id ? classNames(classes.icon, classes.iconMouseHover) : classes.icon} /> },
]
return (
<>
{icons.maps(icon => (
<>
{/* this will not work since it gave me an error saying icon is not defined in array above */}
{icon.icon}
</>
))}
</>
)
}
const useStyles = makeStyles((theme) => ({
icon: {
width: 100,
height: 100,
marginBottom: 12,
},
iconMouseHover: {
color: theme.palette.secondary.main
}
}))
Is there any ways for me to do this dynamically with React?
Something that can change the icon tag but the remaining attributes stay the same:-
// only tag name changes
<OnlyThisChange className={changeIconColor === skill._id ? classNames(classes.icon, classes.iconMouseHover) : classes.icon} />
Is this possible with react?

yes, this possible.
First of all, you don't need to write a key in the icon component. Prop key must be defined in the Fragment element(<> -> <React.Fragment key={icon.id}>).
Your example is almost correct, one mistake that you're doing is:
changeIconColor === icon.id
instead of the above example, you can hardcode your ids:
changeIconColor === 1

Related

Nextjs: Button onclick toggle in sidebar overlay

I have a case regarding the onclick button to open the "choose template" sidebar.
the interface is like this.
So when the button is pressed, the "choose template" sidebar will appear.
However, when I click the button, the sidebar won't appear. do you think that's why? is there something wrong with my coding? Thank you
My Code=
Editor.jsx
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/router";
import styles from "./Editor.module.scss";
import PropTypes from "prop-types";
import { Button } from "../../global/Button";
import ColorPicker from "./ColorPicker";
import "react-edit-text/dist/index.css";
import RightArrow from "../../../public/images/qrcode/rightArrow.svg";
let qrCode;
if (typeof window !== "undefined") {
console.log("i am client");
const QRCodeStyling = require("qr-code-styling");
qrCode = new QRCodeStyling({
width: 1000,
height: 1000,
margin: 50,
qrOptions: { typeNumber: "0", mode: "Byte", errorCorrectionLevel: "Q" },
imageOptions: { hideBackgroundDots: true, imageSize: 0.2, margin: 10 },
dotsOptions: {
type: "rounded",
color: "#756ce0",
gradient: {
type: "radial",
rotation: 0,
colorStops: [
{ offset: 0, color: "#aa80f9" },
{ offset: 1, color: "#756ce0" },
],
},
},
backgroundOptions: { color: "#ffffff", gradient: null },
image: "https://i.ibb.co/SrpHzTQ/icon-200px.png",
dotsOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#6a1a4c", color2: "#6a1a4c", rotation: "0" },
},
cornersSquareOptions: { type: "extra-rounded", color: "#756ce0" },
cornersSquareOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#000000", color2: "#000000", rotation: "0" },
},
cornersDotOptions: { type: "", color: "#613583", gradient: null },
cornersDotOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#000000", color2: "#000000", rotation: "0" },
},
backgroundOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#ffffff", color2: "#ffffff", rotation: "0" },
},
});
}
import { BsFileEarmarkPdfFill } from "react-icons/bs";
import { IoIosArrowBack } from "react-icons/io";
const Editor = ({ isResponsive, template, list, merchant, setActive, color, toggleClick }) => {
const { Template } = template;
const warna = "linear-gradient(180deg, #aa80f9 0%, #756ce0 100%)";
const router = useRouter();
const qrRef = useRef();
const [colorProps, setColorProps] = useState(warna);
useEffect(() => {
setTimeout(() => {
if (qrRef.current) qrCode.append(qrRef.current);
}, 100);
}, [Template]);
useEffect(() => {
qrCode.update({
data: process.env.NEXT_PUBLIC_SHARE_URL + "/" + router.query.shareKey,
});
}, [Template]);
// const handleklik = (e) => {
// console.log('Free pizza!');
// }
return (
<>
<div className={styles.container}>
<ColorPicker colorProps={color} callback={(event) => setColorProps(event)} />
<Button onClick={toggleClick} className={styles.button}>
Open Template
</Button>
<IoIosArrowBack
className={styles.arrow + " " + styles.back}
onClick={() => {
setActive(template.id === 0 ? list.length - 1 : template.id - 1);
}}
/>
<div className={styles.paper_container}>
<Template qrRef={qrRef} merchant={merchant} color={colorProps.hex} isResponsive={isResponsive} />
<div className={styles.paper_overlay} id="paper-overlay">
<BsFileEarmarkPdfFill />
<span>Generating PDF</span>
</div>
</div>
<RightArrow
className={styles.arrow + " " + styles.next}
onClick={() => {
setActive(template.id === list.length - 1 ? 0 : template.id + 1);
}}
/>
</div>
</>
);
};
Editor.propTypes = {
template: PropTypes.string,
list: PropTypes.string,
merchant: PropTypes.string,
setActive: PropTypes.string,
color: PropTypes.string,
isResponsive: PropTypes.bool,
toggleClick: PropTypes.func,
};
export default Editor;
Template.jsx
import { useState, useEffect } from "react";
import Image from "next/image";
import styles from "./Template.module.scss";
import PropTypes from "prop-types";
import { FaCheck } from "react-icons/fa";
import { Button } from "../../global/Button";
const Card = ({ data, active, setActive }) => {
return (
<div className={styles.card} onClick={() => setActive(data.id)}>
<Image src={data.image} alt={"template " + data.id} width={116} height={164} />
{active === data.id && (
<div className={styles.overlay}>
<FaCheck />
</div>
)}
</div>
);
};
const Template = ({ list, active, setActive, download }) => {
const [isResponsive, setResponsive] = useState(typeof window !== "undefined" ? window.innerWidth <= 800 : false);
const [isHide, setHide] = useState(true);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 800) {
setResponsive(true);
} else {
setResponsive(false);
}
};
if (window !== "undefined") window.addEventListener("resize", handleResize);
}, []);
useEffect(() => {
setHide(true);
}, [isResponsive]);
return (
<div className={styles.container}>
<div className={styles.card_container} style={{ right: isHide ? null : 0, position: isResponsive && "fixed" }}>
{isResponsive && !isHide && <div className={styles.template_overlay} onClick={() => setHide(true)} />}
<h3>Pilih Template</h3>
{list.map((template) => {
return <Card data={template} key={template.id} active={active} setActive={setActive} />;
})}
</div>
<Button onClick={download} className={styles.button}>
DOWNLOAD
</Button>
</div>
);
};
Card.propTypes = {
data: PropTypes.string,
active: PropTypes.string,
setActive: PropTypes.string
};
Template.propTypes = {
list: PropTypes.string,
active: PropTypes.string,
setActive: PropTypes.string,
download: PropTypes.string,
isResponsive: PropTypes.bool
};
export default Template;
[sharekey].jsx
import { useState, useEffect } from "react";
import { jsPDF } from "jspdf";
import html2canvas from "html2canvas";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import styles from "./Qrcode.module.scss";
import { useRecoilValue } from "recoil";
import { userProfile } from "../../../utils/recoil";
import Sidebar from "../../../components/global/Wrapper/Sidebar/index";
import Editor from "../../../components/edit-survey/qrcode/Editor";
import Template from "../../../components/edit-survey/qrcode/Template";
import TemplateOne from "../../../components/edit-survey/qrcode/template/One";
import TemplateTwo from "../../../components/edit-survey/qrcode/template/Two";
import TemplateThree from "../../../components/edit-survey/qrcode/template/Three";
import TemplateFour from "../../../components/edit-survey/qrcode/template/Four";
import TemplateFive from "../../../components/edit-survey/qrcode/template/Five";
import TemplateSix from "../../../components/edit-survey/qrcode/template/Six";
const Template1 = "/images/qrcode/Template1.jpg";
const Template2 = "/images/qrcode/Template2.jpg";
const Template3 = "/images/qrcode/Template3.jpg";
const Template4 = "/images/qrcode/Template4.jpg";
const Template5 = "/images/qrcode/Template5.jpg";
const Template6 = "/images/qrcode/Template6.jpg";
const templateList = [
{ Template: TemplateOne, id: 0, image: Template1 },
{ Template: TemplateTwo, id: 1, image: Template2 },
{ Template: TemplateThree, id: 2, image: Template3 },
{ Template: TemplateFour, id: 3, image: Template4 },
{ Template: TemplateFive, id: 4, image: Template5 },
{ Template: TemplateSix, id: 5, image: Template6 },
];
const color = {
r: "170",
g: "128",
b: "249",
a: "1",
};
const Qrcode = () => {
const [activeTemplate, setActiveTemplate] = useState(0);
const profile = useRecoilValue(userProfile);
const [isResponsive, setResponsive] = useState(typeof window !== "undefined" ? window.innerWidth <= 800 : false);
const [isHide, setHide] = useState(true);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 800) {
setResponsive(true);
} else {
setResponsive(false);
}
};
if (window !== "undefined") window.addEventListener("resize", handleResize);
}, []);
useEffect(() => {
setHide(true);
}, [isResponsive]);
const download = () => {
const paper = document.getElementById("paper-pdf");
const overlay = document.getElementById("paper-overlay");
overlay.style.display = "flex";
paper.style.transform = "scale(2)";
html2canvas(paper).then((canvas) => {
const imgData = canvas.toDataURL("image/jpg");
const pdf = new jsPDF({
orientation: "potrait",
unit: "pt",
format: "a5",
});
const imgProps = pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, "JPG", 0, 0, pdfWidth, pdfHeight);
pdf.save("QRCode.pdf");
paper.style.transform = null;
overlay.style.display = null;
});
};
return (
<Sidebar style={{ paddingTop: 0, paddingBottom: 0, paddingRight: 0 }}>
<div className={styles.container}>
<Editor
color={color}
template={templateList[activeTemplate]}
list={templateList}
merchant={profile.merchant}
setActive={setActiveTemplate}
toggleClick={() => setHide(!isHide)}
isResponsive={isResponsive}
/>
<Template list={templateList} active={activeTemplate} setActive={setActiveTemplate} download={download} isResponsive={isResponsive} />
</div>
</Sidebar>
);
};
export const getServerSideProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ["common", "edit-survey"])),
},
});
export default Qrcode;
you should pass down the isHide and setIsHide down to Template component. and remove the isHide, setIsHide useState from the Template component
so in [sharekey].jsx
<Template list={templateList} active={activeTemplate} setActive={setActiveTemplate} download={download} isResponsive={isResponsive} isHide={isHide} setIsHide={setIsHide}/>

React-Elastic-Carousel Custom Arrow

I wanted to get help for adding custom arrows to my react carousel, but I am getting the error for 'type' is not defined no-undef. Can someone please tell me what I am doing wrong? and preferably a solution for the current situation.
Thank you
import Carousel, { consts } from 'react-elastic-carousel';
import LeftArrow from './Assets/Group 1316.svg'
import RightArrow from './Assets/Group 1317.svg'
export default function BootcampNew (props) {
const breakPoints = [
{ width: 1, itemsToShow: 1 },
{ width: 550, itemsToShow: 2 },
{ width: 768, itemsToShow: 3 },
{ width: 900, itemsToShow: 4 },
];
type === consts.PREV;
const myArrow = ({type,onClick, isEdge}) => {
const pointer = type === consts.PREV ? {LeftArrow} : {RightArrow}
return(
<Button onClick={onClick} disabled={isEdge}>{pointer}</Button>
)
}
<Carousel
renderArrow={myArrow}
breakPoints={breakPoints}
pagination={false}>
<CourseCard/>
<Carousel/>
you can't type type === consts.PREV;
without any definition and the only use of it, in this case, is to be inside a condition, the other thing you don't return what's being rendered by the functional component, the below code should solve the problems.
import Carousel, { consts } from 'react-elastic-carousel';
import LeftArrow from './Assets/Group 1316.svg'
import RightArrow from './Assets/Group 1317.svg'
function myArrow({ type, onClick, isEdge }) {
const pointer = type === consts.PREV ? {LeftArrow} : {RightArrow}
return (
<button onClick={onClick} disabled={isEdge}>
{pointer}
</button>
)
}
export default function BootcampNew (props) {
const breakPoints = [
{ width: 1, itemsToShow: 1 },
{ width: 550, itemsToShow: 2 },
{ width: 768, itemsToShow: 3 },
{ width: 900, itemsToShow: 4 },
];
return (
<Carousel renderArrow={myArrow} breakPoints={breakPoints} pagination={false}>
<CourseCard/>
</Carousel>
);
}
const pointer = type === consts.PREV ? : <img src={leftArrow} />:<img src={rightArrow} />

Display data in antd table based on selected item from select option

I need to display data on the antd table based on the selected item from select option.The data that are to be displayed are stored in different variables. For example, if school is selected from select option then the datasource is available in schoolData and similarly for other option.
Here's my code:
import React, { useState } from "react";
import Framework from "../framework/Framework";
import { Dropdown, Button, Table, message, Select } from "antd";
import { DeleteOutlined, DownOutlined, EditOutlined } from "#ant-design/icons";
import { Content } from "antd/lib/layout/layout";
import AddNewButton from "../addNewButton/AddNewButton";
import "./attributes.css";
import DataSource from "./Datasource";
import IconDescription from "../icondescription/IconDescription";
import Modal from "antd/lib/modal/Modal";
import { Option } from "antd/lib/mentions";
const Attributes = () => {
const [page, setPage] = useState(1);
const [isModalVisible, setIsModalVisible] = useState(false)
// const [layer, setLayer] = useState()
const columns = [
{
title: "S.N",
dataIndex: "key",
},
{
title: "Name",
dataIndex: "name",
key: "name",
// render: (text) => <a>{text}</a>,
},
{
title: "Address",
dataIndex: "address",
key: "address",
},
{
title: "Contact No.",
dataIndex: "contactno",
key: "contactno",
},
{
title: "Operation",
dataIndex: "operation",
key: "operation",
render: () => {
return (
<div style={{ display: "flex" }}>
<IconDescription icon={<EditOutlined />} label="Edit" />
<IconDescription icon={<DeleteOutlined />} label="Delete" />
</div>
);
},
},
];
const addAttribute = () => {
setIsModalVisible(true)
}
const modalHandleOk = () => {
setIsModalVisible(false);
};
const modalHandleCancel = () => {
setIsModalVisible(false);
};
const selectLayer = (e) => {
console.log("select layer", e)
}
return (
<Framework>
<Content className="attributes">
<div className="select-addNewBtn-container">
<Select defaultValue="school" style={{ width: 120 }} onChange={selectLayer}>
<Option value="school">School</Option>
<Option value="hospital">Hospital</Option>
<Option value="policeStation">Police Station</Option>
</Select>
<AddNewButton name={"Add New Attribute"} addNewBtn={addAttribute} />
<Modal title={"Add New Attribute"} visible={isModalVisible} centered onCancel={modalHandleCancel} onOk={modalHandleOk}>
</Modal>
</div>
<Table
dataSource={DataSource}
columns={columns}
className="data-table"
pagination={{
size: "small",
pageSize: 6,
hideOnSinglePage: true,
showSizeChanger: false,
}}
/>
</Content>
</Framework>
);
};
export default Attributes;
How do i achieve the desired functionality? Do let me know. Quite a beginner at such things.
Assuming Datasource is just a simple array of data objects, and presumably you have another file eg: 'SchoolData' that you need to switch between when the select option is chosen.
What I'd do to keep it simple is create a react state variable to wrap your data and just set it at will in the onChange of your select.
Example

How can I display an array of images after get the urls React Native

Im trying to display a preview of the picked images after pick them, im using this library import { AssetsSelector } from 'expo-images-picker';
This is the code to pick the image:
import React, { useMemo } from 'react';
import { Text, View, StyleSheet, SafeAreaView, Alert } from 'react-native';
import { AssetsSelector } from 'expo-images-picker';
import { Ionicons } from '#expo/vector-icons';
import { AntDesign } from '#expo/vector-icons';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { MediaType } from 'expo-media-library';
import { useNavigation } from '#react-navigation/core';
export default function App() {
const navigation = useNavigation();
const onSuccess = (data: any) => {
const filteredUri = data.filter(({ uri }) => uri).map(({ uri }) => uri);
navigation.navigate('AddProductScreen',
{
filteredUri: filteredUri,
});
};
const widgetErrors = useMemo(
() => ({
errorTextColor: 'black',
errorMessages: {
hasErrorWithPermissions: 'Please Allow media gallery permissions.',
hasErrorWithLoading: 'There was error while loading images.',
hasErrorWithResizing: 'There was error while loading images.',
hasNoAssets: 'No images found.',
},
}),
[]
);
const widgetSettings = useMemo(
() => ({
getImageMetaData: false,
initialLoad: 100,
assetsType: [MediaType.photo, MediaType.video],
minSelection: 1,
maxSelection: 3,
portraitCols: 4,
landscapeCols: 4,
}),
[]
);
const widgetResize = useMemo(
() => ({
width: 50,
compress: 0.7,
base64: false,
saveTo: 'jpeg',
}),
[]
);
const _textStyle = {
color: 'white',
};
const _buttonStyle = {
backgroundColor: 'orange',
borderRadius: 5,
};
const widgetNavigator = useMemo(
() => ({
Texts: {
finish: 'finish',
back: 'back',
selected: 'selected',
},
midTextColor: 'black',
minSelection: 1,
buttonTextStyle: _textStyle,
buttonStyle: _buttonStyle,
onBack: () => {navigation.goBack()},
onSuccess: (e: any) => onSuccess(e),
}),
[]
);
const widgetStyles = useMemo(
() => ({
margin: 2,
bgColor: 'white',
spinnerColor: 'blue',
widgetWidth: 99,
videoIcon: {
Component: Ionicons,
iconName: 'ios-videocam',
color: 'tomato',
size: 20,
},
selectedIcon: {
Component: Ionicons,
iconName: 'ios-checkmark-circle-outline',
color: 'white',
bg: '#0eb14970',
size: 26,
},
}),
[]
);
return (
<SafeAreaProvider>
<SafeAreaView style={styles.container}>
<View style={styles.container}>
<AssetsSelector
Settings={widgetSettings}
Errors={widgetErrors}
Styles={widgetStyles}
Navigator={widgetNavigator}
/>
</View>
</SafeAreaView>
</SafeAreaProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
This is the code where I want o display the images, im using react navigation props to get the array:
const showPickedImages = ({ route, navigations }) => {
const navigation = useNavigation();
var filteredUri = route.params?.filteredUri;
return(
<View>
//Here I want to show the preview of the picked images
<View/>
)}
You can use Flatlist or ScrollView for this.
<Flatlist
ListEmptyComponent={
<Text>Loading...</Text>} // show loading text until you get the data
data={filteredUri}
renderItem={(uri)=>
<Image source={{uri}} style={{widht:100, height:100}} />
}
/>

How to pass data to different screens

I need to pass data from one screen to anothre, an main screen loads and then loads the data from a mock api, it sets the state with providerData, then navigation gets created. I want to be able to use the data i got in the ProviderDetailScreen.js in ProviderOverview.js
Here is ProviderDetailsScreen.js
import React from 'react';
import {StatusBar, View} from 'react-native';
import ProviderOverview from './ProviderOverview';
import ProviderServicesList from './ProviderServicesList';
import NavigationbarHeaderWithExpandedImage from '../components/NavigationbarHeaderWithExpandedImage';
import TopTabbarComponent from '../components/TopTabbarComponent';
import mockApi from '../mockApi';
const ProviderDetailScreen = ({navigation, route}) => {
const [providerData, setProviderData] = React.useState({});
const [loading, setLoading] = React.useState(false);
//navigation setup
React.useLayoutEffect(() => {
navigation.setOptions({
header: ({scene, previous}) => {
return (
<NavigationbarHeaderWithExpandedImage
scene={scene}
previous={previous}
navigation={navigation}
backgroundImage={providerData?.profile?.backgroundImage}
/>
);
},
});
}, [navigation, providerData]);
//get results from API
const getServices = React.useCallback(async () => {
try {
setLoading(true);
const res = await mockApi.get('/Provider/Profile');
if (res.ok && res.body.data) {
// use this data in overview and service list
setLoading(false);
setProviderData(res.body.data);
} else {
throw new Error('Unable to retrieve profile');
}
} catch (error) {
console.log(error);
}
}, []);
React.useEffect(() => {
console.warn('here');
getServices();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<>
<StatusBar barStyle="light-content" />
<TopTabbarComponent
items={[
{
title: 'Overview',
component: ProviderOverview,
},
{
title: 'Services',
component: ProviderServicesList,
},
{
title: 'Reviews',
component: View,
},
]}
/>
</>
);
};
export default ProviderDetailScreen;
Here is The ToTabbarComponent.js that created a tab for each item in providerdetailsscreen
import React from 'react';
import {StyleSheet} from 'react-native';
import {createMaterialTopTabNavigator} from '#react-navigation/material-top-tabs';
import {PRIMARY, WHITE, INACTIVE_TINT_COLOR, ACCENT} from '../lib/colors';
import fonts from '../lib/fonts';
const Tab = createMaterialTopTabNavigator();
const TopTabbarComponent = ({items}) => {
const tabs = () => {
let tabs = [];
// loop to create tabs
for (const [index, item] of items.entries()) {
tabs.push(
<Tab.Screen
name={item.title}
title={item.title}
component={item.component}
key={index}
/>,
);
}
return tabs;
};
return (
<Tab.Navigator
tabBarOptions={{
activeTintColor: WHITE,
labelStyle: [styles.labelStyle, fonts.medium],
inactiveTintColor: INACTIVE_TINT_COLOR,
style: styles.style,
indicatorStyle: styles.indicatorStyle,
}}>
{tabs()}
</Tab.Navigator>
);
};
const styles = StyleSheet.create({
tabBarOptions: {},
labelStyle: {
fontSize: 14,
},
indicatorStyle: {
backgroundColor: ACCENT,
height: 2,
},
style: {
backgroundColor: PRIMARY,
},
});
export default TopTabbarComponent;
Here is the ProviderOverview.js where i want to use that data that gets set in ProviderDetailsScreen.js
//WANT TO USE DATA HERE
import React from 'react';
import {StyleSheet, View, ScrollView, Text} from 'react-native';
import MediumText from '../components/MediumText';
const ProviderOverview = ({navigation}) => {
return (
<ScrollView style={styles.container}>
<View>
<MediumText onPress={() => navigation.push('PROVIDER_MESSAGE')}>
Send a message
</MediumText>
</View>
<View></View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default ProviderOverview;
I am still learning: Things i have tried:
In providerDetailsscreen i tried to set providerdata for each item, i tried setting a test var with some string to see if i can get it in ProviderOverview. But providerOverview only has Navigation prop.
Thanks in advance.
Try this way
ProviderDetailsScreen.js
<TopTabbarComponent
items={[
{
title: 'Overview',
component: ProviderOverview,
providerData: providerData, // set providerData to ProviderOverview
},
{
title: 'Services',
component: ProviderServicesList,
},
{
title: 'Reviews',
component: View,
},
]}
/>
TopTabbarComponent
// loop to create tabs
for (const [index, item] of items.entries()) {
const CompView = item.component;
const providerData = item.providerData || {};
tabs.push(
<Tab.Screen name={item.title} title={item.title} key={index}>
{(props) => <CompView {...props} {...providerData} />}
</Tab.Screen>
);
}
You can use navigation props
this.props.navigation.navigate('MyData', {data: data,});
https://reactnavigation.org/docs/navigation-prop/#navigate
Or add redux to your project https://redux.js.org/introduction/getting-started

Resources