How to export a class in reactjs - javascript

so im trying to export some classes from my musicplayer file, playlist, setMusicIndex and currentMusicIndex
const playlist = [
{name: 'September', src: september, duration: '3:47'},
{name: 'hello again', src: hello, duration: '04:19'},
]
const MusicPlayer = () => {
const [currentMusicIndex, setMusicIndex] = useState(0)
function handleClickPrevious() {
setMusicIndex(currentMusicIndex === 0 ? playlist.length - 1 : currentMusicIndex - 1)
}
function handleClickNext() {
setMusicIndex(currentMusicIndex < playlist.length - 1 ? currentMusicIndex + 1 : 0)
}
return (
<AudioPlayer
autoPlay={true}
showSkipControls={true}
showJumpControls={false}
volume="0.2"
onClickPrevious={handleClickPrevious}
onClickNext={handleClickNext}
onEnded={handleClickNext}
src={playlist[currentMusicIndex].src}
/>
)
}
export default MusicPlayer;
then i want to import those into my music file to make a playlist,
class Music extends Component {
render() {
return (
<div className="wrapper">
<div className="music-playlist">
<ul>
{playlist.map((song, i) => (
<li
role="menuitem"
tabIndex={0}
onClick={() => setMusicIndex(i)}
onKeyPress={() => { }}
key={i}
className={`${currentMusicIndex === i && 'playing'}`}>
{currentMusicIndex === i && <i className="fa fa-play" aria-hidden="true"></i>} {song.name}
<div className="song-duration">{song.duration}</div>
</li>
))}
</ul>
</div>
</div>
)
}
}
export default Music;
i did read up on exports since im new to js and react, and i tried
export default MusicPlayer, playlist, setMusicIndex, currentMusicIndex;
import MusicPlayer, {playlist, setMusicIndex, currentMusicIndex } from '../../Components/MusicPlayer/MusicPlayer'
import { playlist, setMusicIndex, currentMusicIndex } from '../../Components/MusicPlayer/MusicPlayer'
import * from '../../Components/MusicPlayer/MusicPlayer'
and im still getting error saying
Attempted import error: 'playlist' is not exported from '../../Components/MusicPlayer/MusicPlayer'.
anyone willing to export those for me

In your case these 3 are not classes, playlist is an array, currentMusicIndex is an integer and setMusicIndex is a function, and the three are not exported so you can't import them in another component like this.
you can:
Create a parent container that contains both MusicPlayer and Music, and set the playlist, currentMusicIndex and setMusicIndex in this <ParentContainer />, then pass them as props to its MusicPlayer and Music children
Use Redux
Use React Context

you are only declaring playlist variable but not exporting it. Just add the keyword export for your variable so it becomes a named export:
export const playlist = [
{name: 'September', src: september, duration: '3:47'},
{name: 'hello again', src: hello, duration: '04:19'},
]
then you can just import that using named import:
import {playlist} from ''path/to/your/jsFile'

Related

Use const from another file in Reactjs

I have an object:
import React, {Component} from 'react';
import ProgressBar from "./ProgressBar";
class Languages extends Component {
state = {
languages: [
{id: 1, value: "XXX", xp: 1.5},
{id: 2, value: "CCC", xp: 1},
{id: 3, value: "AAA", xp: 2}
]
}
render() {
let {languages} = this.state;
const levels = ['Test', 'Bad', 'Sorry']
return (
<div className="languages">
<ProgressBar
programming={languages}
className="languagesDisplay"
levels={levels}
title="Languages"
/>
</div>
);
}
}
export default Languages;
import React from 'react';
const ProgressBar = (props) => {
return (
<div className={props.className}>
<h3>{props.title}</h3>
<div className="years">
<span>Experiences</span>
props.levels.map((level) => {
<span>level</span>
})
</div>
<span>level</span> return props.levels.map((level) =>level)
how can i display the const ['Test', 'Bad', 'Sorry'] from Languages.js in a <span> in a different React file?
Edit after seeing your response above: If the issue is just that the above code isn't working, here are a couple of things to check.
Inside of ProgressBar you've got a couple of errors in your JSX. First, you need curly braces around your JavaScript interpolation and secondly, you're not returning anything in your .map() function. If you were using parentheses it would be an implicit return, but with the curly braces you need a return statement. Try this instead:
import React from 'react';
const ProgressBar = (props) => {
return ( <div className={props.className}>
<h3> {props.title} </h3>
<div className ="years">
<span> Experiences </span>
{props.levels.map((level) => {
return (<span>{level}</span>)
})
} </div>
)};
My initial answer, which still may be helpful for understanding what's going on:
It's not entirely clear what you want to do, but here are a couple of things that might be helpful.
What's happening in your code above is that the levels variable, which is an array of strings, is being passed down from the parent component Languages into the child component ProgressBar via the props object.
When ProgressBar is called inside of Languages, it's properties (or props) are set (programming, className, levels, title).
The levels={levels} part means that the prop levels on ProgressBar is being set to the variable levels (the array of strings).
Inside of ProgressBar all of those properties are accessible in the props object that's passed as an argument. That's why you're able to access that array of strings with props.levels.map() which will map the array of strings however you tell it to (in this case by printing each individual item within a <span> tag).
So, with that understanding of what's happening here, here are a couple of things you could do to access the levels variable elsewhere in another file.
If levels is a constant that you want to access in multiple places, you could move it outside of the body of your Languages component and export it to use it in other places.
That could look like:
import React, {
Component
} from 'react';
import ProgressBar from "./ProgressBar";
export const levels = ['Test', 'Bad', 'Sorry']
class Languages extends Component {
state = {
languages: [{
id: 1,
value: "XXX",
xp: 1.5
},
{
id: 2,
value: "CCC",
xp: 1
},
{
id: 3,
value: "AAA",
xp: 2
}
]
}
render() {
let {
languages
} = this.state;
return ( <
div className = "languages" >
<
ProgressBar programming = {
languages
}
className = "languagesDisplay"
levels = {
levels
}
title = "Languages" /
>
<
/div>
);
}
}
export default Languages;
By exporting it from the top level, you could import it in another file exactly as it is.
import { levels } from '/insert-first-file-location-here'
Another option is to pass the levels variable into another component as a prop. This way if levels gets changed at the top level, those changes will drill down into subsequent components.
import React, {Component} from 'react';
import ProgressBar from "./ProgressBar";
class Languages extends Component {
state = {
languages: [
{id: 1, value: "XXX", xp: 1.5},
{id: 2, value: "CCC", xp: 1},
{id: 3, value: "AAA", xp: 2}
]
}
render() {
let {languages} = this.state;
const levels = ['Test', 'Bad', 'Sorry']
return (
<>
<div className="languages">
<ProgressBar
programming={languages}
className="languagesDisplay"
levels={levels}
title="Languages"
/>
</div>
<AnotherComponentThatUsesLevels
levels={levels} />
</>
);
}
}
export default Languages;
And then
import React from 'react'
export const AnotherComponentThatUsesLevels (props) => {
return (
<>
{/* do something with levels here, maybe map them like before*/}
{props.levels.map((level) => (<span>{level}</span>)}
</>
)
}
Does that help understand what's happening in the example and give you a couple of ways you could use that variable in another location?
You need to export that certain constant from your file like that:
import React, {
Component
} from 'react';
import ProgressBar from "./ProgressBar";
export const levels = ['Test', 'Bad', 'Sorry']
class Languages extends Component {
state = {
languages: [{
id: 1,
value: "XXX",
xp: 1.5
},
{
id: 2,
value: "CCC",
xp: 1
},
{
id: 3,
value: "AAA",
xp: 2
}
]
}
render() {
let {
languages
} = this.state;
return (
<div className="languages">
<ProgressBar
programming={languages}
className="languagesDisplay"
levels={levels}
title="Languages"
/>
</div>
);
}
}
export default Languages;
After it, you need to import it in the file where you want to access it:
import {levels} from '/path/to/file';

This expression is not callable. Type '{ Shop: typeof Shop; }' has no call signatures. React

I don't know how and why I'm getting this error in React.
I'm trying to build this components:
render() {
return (
<div>
<div>ShopsList</div>
{this.state.loading || !this.state.shops ?
(
<div></div>
) :
(
<div>
{this.state.shops.map(shop=>Shop(shop))} # Line with the error
</div>
)
}
</div>
)
}
but the program won't compile and gives the following message:
This expression is not callable. Type '{ Shop: typeof Shop; }' has
no call signatures
Shop is imported in the following way
import Shop from '../Shop';
with the folder ../Shop having the following structure:
Shop/
Shop.tsx
index.tsx
and index.tsx has this content:
import Shop from "./Shop";
export default {Shop}
Shop has been defined in this way, which has a constructor:
import React from 'react';
export interface IShopProps {
id: number;
name: string;
phone_number?: string;
}
class Shop extends React.Component<IShopProps, {}> {
constructor(props: IShopProps) {
super(props);
}
render() {
return (
<div className='shopRow'>
<div className='shopName'>{this.props.name}</div>
<div className='shopNumber'>{this.props.phone_number ? this.props.phone_number : "numero non disponibile"}</div>
</div>
)
}
};
export default Shop;
What am I doing wrong? I already tried looking up on SO for that message and I found this post, but to me it doesn't seem I have done the same error.
Edit:
I also tried as suggested by #Viet:
{this.state.shops.map((shop, index) => <Shop key={index} {...shop} />)}
and still get the error:
JSX element type 'Shop' does not have any construct or call
signatures. TS2604
Because Shop is the component so you should use it with <>:
{this.state.shops.map((shop, index) => <Shop key={index} {...shop} />)}
The problem is you import Shop wrong way. Just update import in your component where you use Shop component like this:
import { Shop } from "../Shop" // from index file
Or like this
import Shop from "../Shop/Shop" // from Shop file

I can't export the array I have created in one of my react components

I have been trying to export this array to dynamically render on another page (based on input from fakeApi) within my app and can't get it to work. I'm new to react and not sure if this is the correct way to achieve what I want.
Basically, I would like the full api (yet to create just using fake one for testing) to appear on one page (which is working). Then based on the information received from the array show which networks are down on the homepage of my app. Any help is much appreciated. Please see code.
import NetworkComponent from './NetworkComponent';
let fakeApi = [
{
key: 1,
HostIPAddress: "1.1.1.1",
HostFriendlyName: "BBC",
HostMonitored: "down",
HostType: "VPN"
},
{
key: 2,
HostIPAddress: "8.8.8.8",
HostFriendlyName: "johnlewis.co.uk",
HostMonitored: "ok",
HostType: "VPN"
},
{
key: 3,
HostIPAddress: "2.3.4.5",
HostFriendlyName: "hello.co.uk",
HostMonitored: "down",
HostType: "VPN"
},
];
const NetworkScan = () => {
return (
<div>
<h1>Network Monitor</h1>
<div className="container mx-auto">
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
{fakeApi.map(service => (
<NetworkComponent key={service.key} service={service} />
))}
</div>
{fakeApi.forEach((service) => {
if(service.HostMonitored === "down") {
let networkErr = [];
networkErr.push(service.HostMonitored, service.HostFriendlyName, service.HostIPAddress)
console.log(networkErr);
}
})};
</div>
</div>
);
};
export default NetworkScan;
You can export it as object export { fakeApi } and import it as import { fakeApi } from '../..'
Put that array object into a .json file (i.e. fakeApi.json) and import it like import fakeApi from './fakeApi.json' wherever you want.

convert React Functional Component into Class with Props

I was hoping to find some help with this issue I have been having converting a file into a class based Component. I've struggled with this one for awhile, and I just cannot get the onClick to work correctly. Everything else renders fine, but the click function simply does not work. I would greatly appreciate any tips, feedback, or help!
import * as React from 'react';
import "./bsi-tabs.scss"
import IBsiTabProps from "./ibsi-tab-props"
function Tab ({
onClick = function(){return; },
tabIndex = '',
tabID = ''
}: IBsiTabProps) {
return (
<li>
<a
onClick={(event) => {
event.preventDefault();
onClick(tabIndex);
}}
href="/#"
>
{tabID}
</a>
</li>
);
}
export default BsiTab;
my attempt at conversion :
import * as React from 'react';
import "./bsi-tabs.scss"
import IBsiTabProps from "./ibsi-tab-props"
/*
Credit https://gist.github.com/diegocasmo/5cd978e9c5695aefca0c6a8a19fa4c69 for original
js files, edited by Robert McDonnell to convert to typescript
*/
export class BsiTab extends React.Component<IBsiTabProps, any> {
onClick = function(){return; }
tabIndex = ''
tabID = ''
render(){
return (
<li>
<a
onClick={(event) => {
event.preventDefault();
this.onClick(this.props.tabIndex);
}}
href="/#"
>
{this.props.tabID}
</a>
</li>
);
}
}
export default BsiTab;
interface :
export default interface IBsiTabProps {
onClick ?: Function;
tabIndex ?: Number | string;
tabID: String;
children : React.ReactNode;
}

Fallback message for empty object meteor/react

I would like to show a message if there aren't objects to be returned. Something like: 'currently there are no customers available'.
I tried to tinker a bit with Object.getOwnPropertyNames() but could not get it working because the mapping function does not being called. I'm not sure where to put this check, inside the rendering function, in the with tracker or render call inside the template.
I use Meteor/react and my code looks like this:
import React, {Component} from 'react';
import {withTracker} from 'meteor/react-meteor-data';
import {Link} from 'react-router-dom';
class ArchiveCustomerOverview extends Component {
renderCustomerList() {
return this.props.users.map( user => {
return(
<div className="row" key={user._id}>
<Link to={}>
<span className="medium-1">{user.profile.name}</span>
<span className="medium-4">{user.profile.company}</span>
<span className="medium-3">{user.profile.phone}</span>
<span className="medium-3">{user.emails[0].address}</span>
</Link>
</div>
)
});
}
render() {
return (
<div>
<div className="list-overview">
<div className="list-wrapper">
<div className="list-box clear">
{this.renderCustomerList()}
</div>
</div>
</div>
</div>
);
}
}
export default withTracker( (props) => {
Meteor.subscribe('users');
return {
users: Meteor.users.find({
'profile.isArchived': 0,
'roles.customers' : 'customer'
}).fetch()
};
})(ArchiveCustomerOverview);
Just check on the number of users before you render them like this:
renderCustomerList() {
if (this.props.users.length === 0) {
return (<div>Currently there are no customers available</div>)
}
return this.props.users.map( user => {
But a word of warning: you may not get what you want from the users collection - for security reasons it is treated differently from other collections.

Categories