Warning: Prop `id` did not match in tradingview widget - reactjs

I am trying to use TradingViewWidget in react to show charts but the chart is showing sometimes and sometimes not. Getting this Warning in console
Warning: Prop id did not match. Server: "tradingview-widget-0.7679528527764021" Client: "tradingview-widget-0.3972755056284276"
and this is my code -
import TradingViewWidget from 'react-tradingview-widget';
import { Segment } from 'semantic-ui-react';
const TechnicalChart = () => {
return (
<Segment basic >
<TradingViewWidget symbol="OANDA:USDTHB"/>
</Segment>
);
};
export default TechnicalChart;
What am I doing wrong here?

maybe you are using some sort of server side rendering, I was getting this error in Nextjs, and that was because of SSR, and I did sth like this:
const TvChart = dynamic(() => import("TvChart"), { ssr: false });
and then used it as:
<TvChart/>
and this is the chart component:
import TradingViewWidget from "react-tradingview-widget";
const TvChart = () => {
return <TradingViewWidget symbol="NASDAQ:AAPL" />;
};
export default TvChart;
and now it works well.

Related

React real-time chart with react.context and socket.io

I'm trying to build a website for displaying real-time charts in typescript with react for my learning. But I can not get values from a server properly before displaying the chart.
What I want to do is ...
Communication protocol is websocket using socket.io.
Using socket.io and storing data are inside React.Context(useSocket.tsx) so as to access the data from any react components easily.
Displaying the data is in Home.tsx.
The socket events are initial_data and new_data.
The initial_data event is received at the time the accessing the website at first.
The new_data event is received at regularly.
The time getting both events above, update values inside Home.tsx automatically.
I researched some articles on the web, for example, explaining a way that using socket.io inside a useEffect() function that returning socket.disconnect().
So, the code I built is below.
useSocket.tsx
import {useContext, createContext, useState, useEffect} from "react";
import {io, Socket} from "socket.io-client";
import {chartDataType} from "../types/chartDataType";
type Context = {
chartData: Array<chartDataType>;
}
const SocketContext = createContext<Context>({
chartData: [],
});
const SocketsProvider = (props: any) => {
const [chartData, setChartData] = useState();
useEffect( () => {
const socket: Socket = io("http://***.***.***.***");
socket.on('initial_data', (data) => {
console.log(data);
setChartData(data);
});
socket.on('new_data', (data) => {
console.log(data);
});
return () => { socket.disconnect() };
},[]);
return (
<SocketContext.Provider value={{chartData}} {...props} />
);
}
const useSocket = () => useContext(SocketContext);
export { SocketsProvider, useSocket };
Home.tsx
import {memo, VFC} from "react";
import { useSocket } from "../../context/useSocket";
import {Heading} from "#chakra-ui/react";
export const Home: VFC = memo(() => {
const { chartData } = useSocket();
return (
<>
<Heading as="h1">{`${chartData}`}</Heading>
</>
)
})
The above code caused an error Uncaught TypeError: Cannot read properties of undefined (reading '0') occurred in the browser console. But when the comment out the <Heading>...</Heading> line in Home.tsx, the console.log in useSocket.tsx can display the value from the server in the browser console.
I can not come up with the idea for the correct implementation. Is the definition of the type of the chartData wrong? or other reasons? The definition of the chartDataType has nothing wrong.
What is the way for the correct implementation?
What's happening is you are trying to render an empty array, the data hasn't loaded yet.
You need to check if charData exists, or if it's undefined first.
Like this:
return (
{CharData ? <Heading /> ... : null }
)

Nextjs, react and TypeScript: prop type missing on FC using getInitialProps when used

I have a very basic React and Nextjs project built in TypeScript. I'm currently building this project from scratch to understand Nextjs better, I'm already quite proficient with TypeScript and React.
I have a simple Clock component built like below, and as per the nextjs documentation.
import { NextPage } from 'next';
import React, { useEffect } from 'react';
type Props = {
isoTime: string
}
const Clock: NextPage<Props> = ({ isoTime }: Props) => {
return <p>{isoTime}</p>;
}
Clock.getInitialProps = async () => {
return {
isoTime: new Date().toISOString()
};
};
export default Clock;
No problems here, however when I try and use this component elsewhere, for example in my app component...
import React from 'react';
import Clock from './clock/Clock';
function App() {
return (
<div className="App">
<Clock />
</div>
);
}
export default App;
I get the TypeScript error Property 'isoTime' is missing in type '{}' but required in type 'Props'. If I add a {/*#ts-ignore*/} above the error it compiles and works as expected, however I shouldn't have to remove typesafety just to get this to compile. How can I get TypeScript to pick up the props coming from getInitialProps?
According to nextJS documentation the put it as a optional props
interface Props {
userAgent?: string;
}
const Page: NextPage<Props> = ({ userAgent }) => (
<main>Your user agent: {userAgent}</main>
)
Page.getInitialProps = async ({ req }) => {
const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
return { userAgent }
}
export default Page
From you code it will be like this
type Props = {
isoTime?: string
}

NextJS issue with server side rendering with react-d3-tree

To start off, I have looked at issue number 40 and 95 on the react-d3-tree github
I don't see anything on StackOverflow that would help me. I am trying to implement the parseJSON method so I can take my own JSON file from the project folder and then generate a tree diagram.
Let's start from what I did in the beginning. I copy pasted the example code which worked for 2 seconds before crashing. Reason? Server Side Rendering. Great, so then I find this from NextJS which allows me to disable SSR for some components. Hey, now the example code is working. Let's try the example code where they use external data! Nope, it can't find the parseJSON method. I have no idea what to do, can't find anything to fix this. I am trying to import this function that has some issue with SSR, but because it isn't a component I am not able to import it using dynamic, and I can't import normally because it causes a "window is not defined" error because of SSR.
The following are my main two files.
DynamicComponent.js [Version 1]
import dynamic from 'next/dynamic';
const Tree = dynamic(
() => import('react-d3-tree'),
{ ssr: false },
);
export default Tree;
DynamicComponent.js [Version 2]
import dynamic from 'next/dynamic';
export const Tree = dynamic(
() => import('react-d3-tree'),
{ ssr: false },
);
export const treeUtil = dynamic(
() => import('react-d3-tree/src/util'),
{ ssr: false },
);
Diagram/index.js
import React from 'react';
import { Tree, treeUtil } from '../DynamicComponent';
const myTreeData = require('../fakeData.json');
class Diagram extends React.PureComponent {
constructor() {
super();
this.state = {
data: undefined,
};
}
componentWillMount() {
treeUtil.parseJSON(myTreeData)
.then((data) => {
this.setState({ data });
});
}
render() {
return (
<div
id="treeWrapper"
style={{ width: '50em', height: '20em' }}
>
<Tree data={this.state.data} />
</div>
);
}
}
export default Diagram;
Error I Get with Version 1
ReferenceError: treeUtil is not defined
Error I Get with Version 2
TypeError: _DynamicComponent__WEBPACK_IMPORTED_MODULE_1__.treeUtil.parseJSON is not a function
Please StackOverflow, you're my only hope.
I ran into the same problem with Cytoscape, a similar library (but specifically for graph-network visualization). It took lots of trial and error, but the solution was:
import the component dynamically
remove the import JSON and inline it into a js file. For some stupid reason, that worked for me and was the magic fix. (how big was your JSON file?) Worse-case try copying & pasting into the component itself.
For your component try this:
// convert fakeData.json to fakeData.js
export default {...fake data here };
import React from 'react';
import dynamic from 'next/dynamic'
import myTreeData from 'fakeData';
const Tree = dynamic(
() => import('./dynamicComponent'),
{ ssr: false }
);
// you can also delineate a loading component;
// converted to hooks for '21
const Diagram = () => {
const [data,setData] = useState({});
useEffect(() => {
treeUtil.parseJSON(myTreeData)
.then((data) => {
setData(data);
})
},[treeUtil,myTreeData,setData]);
return (
<div
id="treeWrapper"
style={{ width: '50em', height: '20em' }}
>
<Tree data={data} />
</div>
);
}
export default Diagram;
I guess treeUtil is not a react component, so you can't use dynamic to import it. Just import it normally may be work.
import dynamic from 'next/dynamic';
export const Tree = dynamic(
() => import('react-d3-tree'),
{ ssr: false },
);
export { default as treeUtil } from 'react-d3-tree/src/util';

How to use portals in Next.js in getting the child element outside the immediate parent container?

Current Implementation
Container
export const FormContainer = () => {
return (<Form/>);
}
Component
export const Form = () => {
return ReactDOM.createPortal(
<aside>
<div>{"I am a component"}<div/>
</aside>,
document.body
);
}
Errors
ReferenceError: document is not defined
Expectation
I want the Form to be out of FormContainer DOM hierarchy.
ReferenceError: document is not defined
ReactDOM.createPortal is more like a "BrowserSide only" component because it needs document and in serverSide Rendering, it's undefined.
I want the Form to be out of FormContainer DOM hierarchy.
easiest solution:
set a condition to check for BrowserOnly rendering of createPortal component :
according to saimeunt answer, something like
export const FormContainer = () => {
return (
{process.browser?
<Form/>:null
}
);
}
will make the day.
another way around will be using nextJs dynamic import and disable SSR on module
import dynamic from "next/dynamic";
const Form = dynamic(() => import("path/to/FormModule"), { ssr: false });
export const FormContainer = () => {
return (<Form/>);
}

Using switch statement with dynamic components in NextJS

I am trying to use dynamic import in NextJS and I do not understand why it works only while storing imported component in a variable. It breaks when I try to return it from other function.
It works this way:
import dynamic from "next/dynamic";
const Article = dynamic(() => import("tutorial/ru/welcome.mdx"));
but like this, well, it breaks:
import dynamic from "next/dynamic";
export default ({ route }) => {
switch (route) {
case "ru":
default:
return dynamic(() => import("tutorial/ru/welcome.mdx"));
}
};
I get the Invalid hook call. Hooks can only be called inside of the body of a function component message.
I think you need to export it , then try to use it like so :
import dynamic from "next/dynamic";
const Article = dynamic(() => import("tutorial/ru/welcome.mdx"));
export default Article;
then try to use it in switch statement :
import Article from './Article';
export default ({ route }) => {
switch (route) {
case "ru":
return (<></>)
default:
return <Article />;
}
};
I found a solution to get over this issue!
import dynamic from "next/dynamic";
import Loader from "components/Loader/Loader";
import Error from "pages/_error";
export default ({ route }) => {
const Article = dynamic(
() => import(`tutorial/${route}.mdx`).catch(err => {
return () => <Error />
}),
{ loading: () => <Loader /> }
);
return <Article />
};
I should store the component in the variable after all, but I get the component itself dynamically using literal strings, and after that I return the component as tag (). Works fine now!

Resources