How to use wavesurfer.js in React? - reactjs

i'm trying to render audio files using wavesurfer.js in my react app. I'm a noob and I'm wondering why I'm getting a "Container element not found" message all the time.
This is what i need to know in a nutshell.
THank you in advance!
import React from "react";
import WaveSurfer from "wavesurfer.js";
export default function Chat(){
const wavesurfer = WaveSurfer.create({
container: "#waveform",
});
render(
<>
<div id="waveform">
</div>
</>
)
}

You are currently calling that in the render function, which would mean it is executed everytime the component refreshes. Instead you can add it in a useEffect hook so that the waveform function is called only once and the element you are binding it to is present.
Also, you can use a ref instead of the ID, which is what React uses to refer to DOM elements.
import React, { useRef, useEffect } from "react";
import WaveSurfer from "wavesurfer.js";
export default function Chat(){
const waveformRef = useRef();
useEffect(() => {
if(waveformRef.current) {
const wavesurfer = WaveSurfer.create({
container: waveformRef.current,
});
}
}, []);
return(
<>
<div ref={waveformRef}>
</div>
</>
)
}
useEffect
Refs

Related

Is there a hook/method etc. in NextJs that is equivalent to the createRef() hook in original ReactJs?

I am trying to use 3rd party package ReactPhotoSphereViewer in NextJs to display panoramic images in the website.
The package works both in NextJs and in ReactJs.
Here is the code that is works in ReactJs:
import { ReactPhotoSphereViewer } from 'react-photo-sphere-viewer';
import React, {createRef, useEffect} from 'react';
...
function PanoramaImage({src}) {
return (
<ReactPhotoSphereViewer
src={src}
></ReactPhotoSphereViewer>
);
}
...
export default PanoramaImage;
Here is the code for same purpose in NextJs:
import React, {createRef, useEffect} from "react";
import dynamic from 'next/dynamic'
const ReactPhotoSphereViewer = dynamic(
() =>
import('react-photo-sphere-viewer').then(
(mod) => mod.ReactPhotoSphereViewer
),
{
ssr: false,
}
)
...
function PanoramaImage({src}) {
return (
<div>
<ReactPhotoSphereViewer
src={src}
></ReactPhotoSphereViewer>
</div>
)
}
...
export default PanoramaImage;
However when I tried to add reference to the ReactPhotoSphereViewer component, it works in ReactJs, but not in NextJs.
Here is the code after adding reference.
...
function PanoramaImage({src}) {
const photoSphereRef = createRef(<ReactPhotoSphereViewer />);
React.useEffect(() => {
if (!photoSphereRef.current)
return;
photoSphereRef.current.toggleAutorotate();
}, [photoSphereRef]);
return (
<div>
<ReactPhotoSphereViewer
ref={photoSphereRef}
src={src}
></ReactPhotoSphereViewer>
</div>
)
}
...
export default PanoramaImage;
I think the problem is createRef hook here. So, is there any method that I can use instead of createRef, or if I am using it wrong, how should it be correct.
I would be glad if you help. Thank you.
edit: The problem is not on the createRef, I used useRef instead of createRef for both ReactJs and NextJs frameworks, ReactJs works perfectly, but I don't know why, NextJs does not detect the reference.
Finally I gave up using NextJs and start working with ReactJs.
Thank you for everybody.
Use useRef hook.
The difference is that createRef will create a new ref on render.
With functional components you need the same ref each time. useRef does it.
function PanoramaImage({src}) {
const photoSphereRef = useRef();
React.useEffect(() => {
if (!photoSphereRef.current)
return;
photoSphereRef.current.toggleAutorotate();
}, [photoSphereRef]);
return (
<div>
<ReactPhotoSphereViewer
ref={photoSphereRef}
src={src}
></ReactPhotoSphereViewer>
</div>
)
}
...
export default PanoramaImage;
import './App.css';
import React, { useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';
// import { ReactPhotoSphereViewer } from 'react-photo-sphere-viewer';
const ReactPhotoSphereViewer = dynamic(
() =>
import('react-photo-sphere-viewer').then(
(mod) => mod.ReactPhotoSphereViewer
),
{
ssr: false,
}
);
export default function Home() {
return (
<div className="App">
<ReactPhotoSphereViewer src="Test_Pano.jpg" height={'100vh'} width={"100%"}></ReactPhotoSphereViewer>
</div>
);
}
Source: NPM
Or take a look at this code sandbox: https://codesandbox.io/s/sandbox-react-photo-sphere-viewer-by-elius94-j064sm?file=/src/App.js
(Credit to original author elius94)

React JS coponent not rendering using map function

I hava a component called videoRow i try to render this component using dummy values now i get data from a useEffect Hook i have to use that data to render my component but when i try to do so it dont show anything. I even try console log to check weather i get my data or not it print my data on console means my useEffect is working But when i try this data on my videoRow component it not show anything
import React, { useState, useEffect } from "react";
import "../css/searchPage.css";
import TuneSharpIcon from "#mui/icons-material/TuneSharp";
import ChannelRow from "./ChannelRow";
import VideoRow from "./VideoRow";
import { selectInput } from "../features/inputSlice";
import { useSelector } from "react-redux";
import Axios from "axios";
function SearchPage() {
const getQuery = useSelector(selectInput);
const API_URL = `https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=4&key=APIKEY&type=video&q=${getQuery.input}`;
const [data, setData] = useState([]);
useEffect(() => {
async function fetchData() {
let request = await Axios.get(API_URL);
setData(request);
}
fetchData();
}, [API_URL]);
console.log(data);
return (
<div className="searchPage">
<div className="filter">
<TuneSharpIcon></TuneSharpIcon>
<h2>FILTERS</h2>
</div>
<hr></hr>
<ChannelRow
image="https://images.indianexpress.com/2022/01/Republic-Day_1200_AP2022.jpg"
channelName="Dummy"
verified
subs="670k"
noOfVideos={567}
desc="You can find awesome programming lessons here! Also, expect programming tips and tricks that will take your coding skills to the ..."
></ChannelRow>
<hr></hr>
{data?.data?.items?.forEach((item) => {
console.log(item.snippet.title);
console.log(item?.snippet.thumbnails.high.url)
console.log(item?.snippet.publishedAt)
console.log(item?.snippet.description)
console.log(item?.snippet.channelTitle)
return(<VideoRow
image={item?.snippet.thumbnails.high.url}
channelName={item?.channelTitle}
timestamp={item?.snippet.publishedAt}
title={item?.snippet.title}
desc={item?.snippet.description}
views="1.4M"
subs="1.4M"
></VideoRow>)
})}
</div>
);
}
export default SearchPage;
Change data?.data?.items?.forEach to data?.data?.items?.map. forEach returns nothing. So, even if you return the component from the callback, forEach will just ignore it. But, map will return all transformed results as an array.
You can read more about lists in react here.

React Hook "useSelector" is called in function "posts" that is neither a React function component nor a custom React Hook function

Posts.js
import React from 'react'
import Post from './Post/Post'
import UseStyles from "./style"
import {useSelector} from "react-redux"
function posts() {
const classes= UseStyles()
const Posts=useSelector((state)=>state.Posts) //This state refers the to the whole redux store and in this state.Post, post is coming form the Reducers/index.js
console.log(Posts)
return (
<div>
<h1>POSTS</h1>
<Post/>
<Post/>
</div>
)
}
export default posts
index.js
import { combineReducers } from "redux";
import Posts from "./Posts";
export default combineReducers({ Posts })
src\Components\Posts\Posts.js
Line 7:17: React Hook "useSelector" is called in function "posts" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use" react-hooks/rules-of-hooks
this is the actual error. At first it was state.posts as mentioned in this error then I changed it, still it shows the same error, I also restart my server but nothing new is happend.
Proper React components are PascalCased. You should also move the console log into an useEffect so it's an intentional side-effect in what's otherwise considered a pure function.
...
import useStyles from "./style"
...
function Posts() {
const classes = useStyles();
const posts = useSelector((state) => state.Posts);
useEffect(() => {
console.log(posts);
}, [posts])'
return (
<div>
<h1>POSTS</h1>
<Post/>
<Post/>
</div>
);
}
export default Posts;

React.js - passing functions between components using Context API - not working

I am trying to pass a function between two components but even though I do not have any errors, the function that I am passing wont show or to be precise it is not working. I have two files and one of them is creating a context while the other is using it (obviously). Now, they are not shown in App.js (which is rendered in index.js, usual stuff) they are in the seperate folder. I am using React Router to show one the pages (News.js).
Here are the files:
NewsContext.js
import React, { useContext, createContext, useState, useEffect } from "react";
export const newsK = React.createContext();
export const NewsContext = (props) => {
const working = () => {
console.log("it is working");
};
return <newsK.Provider value={working}>{props.children}</newsK.Provider>;
};
export default NewsContext;
News.js
import React, { useContext, useState, useEffect } from "react";
import { newsK } from "./NewsContext";
import { NewsContext } from "./NewsContext";
const News = () => {
const data = useContext(newsK);
return (
<NewsContext>
<div>
<button onClick={data}></button>
</div>
</NewsContext>
);
};
export default News;
When i pressed the button, it wont do anything. Any tips?
You're trying to use context outside the NewsContext component
The solution for this will be to create a component that will call useContext inside NewsContext.
I.e.
const WrappedButton = () => {
const data = useContext(newsK)
return <button onClick={data} />
}
And then put it inside the NewsContext:
<NewsContext>
<div>
<WrappedButton />
</div>
</NewsContext>

How to position the react flatpickr inside a container instead of body

I am having a use case where i have to position the react flatpickr on the left or right side of the input element instead of above or below.
When using the flatpickr i noticed that the flatpickr gets added to the body of dom. Instead i want to add it to container div. so I am passing the appendTo option with container HTMLElement as value. But its not working as expected and still appending to the body tag.*
here is the code snippet i used.
import React, {useState, useRef} from 'react';
import Flatpickr from 'react-flatpickr';
const DateFilter = props => {
const {setDateTime} = props;
const containerRef = useRef() ;
const container = containerRef.current;
return (
<div ref={containerRef}>
<Flatpickr
appendTo={container}
onChange={date => setDateTime(date)}
enableTime={false}
dateFormat={"Y-m-d"}
/>
</div>
)
}
export default DateFilter;
The calendar still gets added to the body.
Contianer DOM post page load
Clearly i am doing something wrong. Any help is much appreciated. Thanks in Advance.
I found why it was not appending by inspecting the
1. React flatpicker Index.js
2. Core flatpicker.js files
The options (appendTo) wasn't received in react-flatpickr because it should be passed inside an object and not as a direct value.
import React, {useState, useRef} from 'react';
import Flatpickr from 'react-flatpickr';
const DateFilter = props => {
const {setDateTime} = props;
const containerRef = useRef() ;
const container = containerRef.current;
const getOptions = () => {
return {
appendTo : container,
enableTime : false,
dateFormat : "Y-m-d"
}
}
return (
<div ref={containerRef}>
<Flatpickr
onChange={date => setDateTime(date)}
options={getOptions()}
/>
</div>
)
}
export default DateFilter;
And also make sure you pass the correct HTMLElement on the first render. Else if you pass undefined it will still load it in Body.

Resources