No get query sting data in react - javascript

I'm trying to get query string parameters tho, it's blank.
This is URL.
https://master.deeiswmgeowge.amplifyapp.com/?site=gfg&subject=react
Then, this.props is empty.
The below is the source.
import React, { Component } from "react";
// Importing Module
import queryString from 'query-string'
class App extends Component {
state = {
site: 'unknown',
subject: 'i dont know'
}
handleQueryString = () => {
// Parsing the query string
// Using parse method
console.log(`this.props`, this.props)
let queries = queryString.parse(this.props.location.search)
console.log(queries)
this.setState(queries)
}
render() {
return (
<div style={{ margin: 200 }}>
<p> WebSite: {this.state.site} </p>
<p> Subject: {this.state.subject} </p>
<button
onClick={this.handleQueryString}
className='btn btn-primary'>
click me
</button>
</div>
);
}
}
export default App;
"dependencies": {
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"query-string": "^6.14.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.2",
"web-vitals": "^1.0.1"
},
This is the error image.

You're not using react router , thus no location parameter in props :
so you have two solution ,
1 whether adding react-router-dom and wrap your app with router , ( or using with router hook like export default withRouter(App))
2 or access directly window.location.search and get params with URLSearchParams
by example :
const urlParams = new URLSearchParams(window.location.search);
const site = urlParams.get('site');
const subject = urlParams.get('subject');

Need to pass the props like
onClick={()=> this.handleQueryString(this.props)}
and received like
handleQueryString(arg) {
....
}

Related

Uncaught Error in react component invalid hook, useSWR

using a useSWR wrapper and I cannot find the issue that is causing the invalid hook error in the Player component.
I went through https://reactjs.org/warnings/invalid-hook-call-warning.html and https://reactjs.org/docs/hooks-rules.html
I didnt have this problem before with react useContext. I refactored and switched to useSWR, router v6. The error is new
error details:
react-dom.development.js:18687 The above error occurred in one of your React components:
...
line 115341
line 115342 e.default = function (n) {
line 115343 var e = n.title,
line 115344 t = void 0 !== e && e,
line 115345 a = n.subTitle,
...
at e.default (http://localhost:3000/static/js/bundle.js:115343:15)
at div
at Player (http://localhost:3000/static/js/bundle.js:8314:108)
at div
at div
at Tab (http://localhost:3000/static/js/bundle.js:6132:104)
at Routes (http://localhost:3000/static/js/bundle.js:122353:5)
at Router (http://localhost:3000/static/js/bundle.js:122286:15)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:121095:5)
at SWRConfig$1 (http://localhost:3000/static/js/bundle.js:137530:21)
at App (http://localhost:3000/static/js/bundle.js:2528:86)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
react-dom.development.js:12056 Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
at resolveDispatcher (react.development.js:1476:1)
at useRef (react.development.js:1515:1)
at e.default (ReactNetflixPlayer.js:1:1)
at renderWithHooks (react-dom.development.js:16305:1)
at mountIndeterminateComponent (react-dom.development.js:20074:1)
at beginWork (react-dom.development.js:21587:1)
at beginWork$1 (react-dom.development.js:27426:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
at renderRootSync (react-dom.development.js:26434:1)
here is the package.json
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-netflix-player": "^1.1.7",
"react-redux": "^8.0.2",
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
"redux": "^4.2.0",
"swr": "^1.3.0"
},
here is the code
// useSharedState.js
---
import useSWR from 'swr'
export const useSharedState = (key, initial) => {
const { data: state, mutate: setState } = useSWR(key, {
fallbackData: initial,
})
return [state, setState]
}
// Container.js
---
import { useSharedState } from "../../hooks/useSharedState"
import useSWR from 'swr'
function Container() {
const { data: item } = useSWR(`/endpoint`)
return (
item && (
<div><button
onClick={() => {setPlayerItem(item) }} ... >
...</div>
);
}
export default Container;
// Player.js
---
import React, { useEffect, useContext } from 'react';
import ReactNetflixPlayer from "react-netflix-player";
const Player = () => {
const [playerItem, setPlayerItem] = useSharedState('playerContext')
return (
<React.Fragment>
{playerItem && (
<div id={"player"} >
<ReactNetflixPlayer
title={playerItem.title}
backButton={() => { setPlayerItem(null) }}
/>
</div>
)}
</React.Fragment>
);
}
export default Player;
// Tab.js
---
import Player from "../Player"
...
function Tab() {
return (
<div>
<Player />
<React.Fragment>
<Container />
{columnData && <BodyColumn data={columnData}/>}
...
</React.Fragment>
</div>
);
}
export default Tab;
<Tab> is a component in <App>
The Player component is rendered after a button is clicked that sets data
there are other components with buttons that perform a click and set state by referencing const [playerItem, setPlayerItem] = useSharedState('playerContext')
thanks in advance
related invalid hook call with SWR library
edit: https://codesandbox.io/s/invalid-hook-debugging-2v37wj

React LeafletJs Map doesn't re-render even on state change? [duplicate]

I'm a new leaflet user for my Typescript and Hook based React application. In my app my current geolocation position(latitude, longitude) is taken(I've allowed the permission to the browser) using the chrome browser's geolocation API by the app and should be shown in the map with a marker. The issue is, the map is always displayed with the initial default position([0,0]). That is, the new position update taken from geolocation API is not displayed.
The issue might be simple but I couldn't understand what I'm missing here that the Leaflet map is not taking my updated position. I checked, new position values are printed correctly, even I rendered just the updated position values inside a simple div, the new values are rendered correctly. Here is my code as below. Any help is much appreciated.
App.tsx
import React from 'react';
import './App.css';
import { Container } from '#material-ui/core';
import {Route,Switch} from 'react-router-dom';
import Header from './components/Header';
import SideBar from './components/SideBar';
import ShowInGoogleMap from './components/ShowInGoogleMap';
import ShowInLeafletMap from './components/ShowInLeafletMap';
function App() {
return (
<div className="app-div">
<Header/>
<div className="main-content">
<SideBar/>
<div className="map-content">
<Switch>
<Route path="/google-map" component={ShowInGoogleMap}/>
<Route path="/leaflet-map" component={ShowInLeafletMap}/>
</Switch>
</div>
</div>
</div>
);
}
export default App;
###############################
ShowInLeafletMap.tsx - this is the function handling Leaflet map
import { LatLngExpression } from 'leaflet';
import React, { useState, useEffect } from 'react';
import 'leaflet/dist/leaflet.css';
import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet';
const ShowInLeafletMap = () => {
const [position, setPosition] = useState<LatLngExpression>([0,0]);
useEffect(() => {
if ("geolocation" in navigator) {
console.log("Available...");
navigator.geolocation.getCurrentPosition(function(cPosition) {
console.log("Latitude is :", cPosition.coords.latitude);
console.log("Longitude is :", cPosition.coords.longitude);
setPosition([cPosition.coords.latitude,cPosition.coords.longitude]);
});
} else {
console.log("Not Available");
}
}, []);
console.log('this is loaded, ', position);
return(
<MapContainer center={position} zoom={13} scrollWheelZoom={false}>
<TileLayer
attribution='© OpenStreetMap contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>
Hi I just found Dresden
</Popup>
</Marker>
</MapContainer>
)
}
export default ShowInLeafletMap;
Here is dependency block of my package.json. I've no dev dependecies for the time being.
"dependencies": {
"#material-ui/core": "^4.11.4",
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"#types/googlemaps": "^3.43.3",
"#types/jest": "^26.0.15",
"#types/node": "^12.0.0",
"#types/react": "^17.0.0",
"#types/react-dom": "^17.0.0",
"#types/react-leaflet": "^2.8.1",
"#types/react-router-dom": "^5.1.7",
"leaflet": "^1.7.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-leaflet": "^3.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1"
},
In react-leaflet version 3, most props are immutable. As for the MapContainer itself:
Except for its children, MapContainer props are immutable: changing them after they have been set a first time will have no effect on the Map instance or its container.
You're better off using the whenCreated prop to capture a reference to the underlying L.map instance in a state variable, then using leaflet methods directly:
const ShowInLeafletMap = () => {
const [map, setMap] = useState<L.Map>()
useEffect(() => {
if ("geolocation" in navigator && map) {
navigator.geolocation.getCurrentPosition(function(cPosition) {
map.panTo([cPosition.coords.latitude,cPosition.coords.longitude]);
});
}
}, [map])
return (
<MapContainer whenCreated(setMap)>
...
</MapContainer>
)
}
Working codesandbox
In leaflet v.4 I used this anti-pattern to rerender (wondering about their documentation):
<MapContainer key={new Date().getTime()} ...>

React.js State is not defined in class component

I am using a class component without a constructor to initialize state. Today, every react app i have tried to create has given me an error
Line 4:3: 'state' is not defined no-undef
my code is
class Page extends Component {
state = {
pages: []
}
render() {
return(
<div>page</div>
);
}
}
export default Page;
the weird part is in my old react apps it works fine. but every new 'npx create-react-app <>' i have tried today all give me undefined unless i use a class constructor.
here are my dependencies
"dependencies": {
"#testing-library/jest-dom": "^5.11.9",
"#testing-library/react": "^11.2.5",
"#testing-library/user-event": "^12.7.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.0"
Seems there is an issue with React version 16.3.1
I was having this issue today and came to this thread. Finally, after upgrading my npm react version from 16.3.1 to 16.4.0, my code is free of this issue.
Class component should be like this. Reference link of documentation here
class Page extends Component {
constructor(props){
super(props);
this.state = {
pages: []
}
}
render() {
return(
<div>page</div>
);
}
}
export default Page;
import React from 'react'
class Page extends React.Component{
state = {
pages: []
}
render() {
return(
<div>page</div>
);
}
}
export default Page;

Cornerstone Tools do not work (after following doc)

first of all,please be patient with this post, because this is my first question here on the platform.
Currently I'm trying to display some .dcm images using Cornerstone. This has worked and looks good.
But since a few days I have the problem that I can't get a simple tool from Cornerstone tools to work with it.
My goal was to start with the wwwc-tool and then the stack-scrolling.
I worked strictly after documentation, but it is simply not possible for me to include any tool. I just don't see the error and don't get any error output.
Can you help me with that?
import React, { useState, useEffect, useRef } from "react";
import { makeStyles } from "#material-ui/core/styles";
import cornerstone from "cornerstone-core";
import cornerstoneMath from "cornerstone-math";
import cornerstoneTools from "cornerstone-tools";
import Hammer from "hammerjs";
cornerstoneTools.external.cornerstone = cornerstone;
cornerstoneTools.external.Hammer = Hammer;
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
cornerstoneTools.init();
export default function Dummy() {
const dicomRef = useRef();
const imageIds = [
"wadouri:http://127.0.0.1:8080/api/challenges/1/series/1/images/1",
"wadouri:http://127.0.0.1:8080/api/challenges/1/series/2/images/1",
"wadouri:http://127.0.0.1:8080/api/challenges/1/series/3/images/1",
];
// define the stack
const stack = {
currentImageIdIndex: 0,
imageIds,
};
// Add our tool, and set it's mode
const { LengthTool } = cornerstoneTools;
useEffect(() => {
// Enable the DOM Element for use with Cornerstone
const element = document.getElementById("navbar");
cornerstone.enable(element);
cornerstone.loadImage(`${imageIds[0]}`).then((image) => {
cornerstone.displayImage(element, image);
cornerstoneTools.addTool(LengthTool);
cornerstoneTools.addToolForElement(element, LengthTool);
cornerstoneTools.setToolActive(LengthTool.name, { mouseButtonMask: 1 });
});
}, []);
return <div ref={dicomRef}>aaa</div>;
}
My dependencys are as follow:
"dependencies": {
"#material-ui/core": "^4.9.14",
"#material-ui/icons": "^4.9.1",
"bootstrap": "^4.5.0",
"cornerstone-core": "^2.2.4",
"cornerstone-math": "^0.1.6",
"cornerstone-tools": "^3.19.3",
"cornerstone-wado-image-loader": "^3.1.1",
"daikon": "^1.2.42",
"dicom-parser": "^1.8.5",
"hammerjs": "^2.0.8",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-lottie-light": "^1.2.5",
"react-scripts": "3.4.1"},
I just want to display the Viewer with the tools in returning div.
Can you try changing useEffect() to:
useEffect(() => {
// Enable the DOM Element for use with Cornerstone
const element = document.getElementById("navbar");
cornerstone.enable(element);
cornerstone.loadImage(`${imageIds[0]}`).then((image) => {
const viewport = cornerstone.getDefaultViewportForImage(element, image);
cornerstone.displayImage(element, image, viewport);
const LengthTool = cornerstoneTools.LengthTool;
cornerstoneTools.addTool(LengthTool)
cornerstoneTools.setToolActive('Length', { mouseButtonMask: 1 })
});
}, []);

how to add this external vue component in my laravel5.3 project?

I try to add http://gritcode.github.io/gritcode-components/#/wizard in my laravel 5.3 project but when i used its nothing showing in my view here is i'm getting console "Uncaught ReferenceError: gritcode is not defined"
my app.js is.
require('./bootstrap');
Vue.component('example', require('./components/Example.vue'));
new Vue({ components: { 'vs-toast': gritcode-components.toast }})
const app = new Vue({
el: '#app',
});
and my welcome.blade.php
<div id="app">
<vs-toast>
<vs-wizard :current-index.sync="currentStep">
<vs-wizard-step
title="Personal Information"
description="Enter your details"
:progress="progress.step1"
icon="person">
</vs-wizard-step>
<vs-wizard-step
title="Payment"
description="Pay with credit card or Paypal"
:progress="progress.step2"
icon="credit-card">
</vs-wizard-step>
<vs-wizard-step
title="Confirmation"
description="Your order details"
:progress="progress.step3"
:disable-previous="true"
icon="check">
</vs-wizard-step>
</vs-wizard>
</vs-toast>
</div>
my package.json
{
"private": true,
"scripts": {
"prod": "gulp --production",
"dev": "gulp watch"
},
"devDependencies": {
"babel": "^6.5.2",
"babel-core": "^6.21.0",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.18.0",
"bootstrap-sass": "^3.3.7",
"gritcode-components": "^0.4.7",
"gulp": "^3.9.1",
"jquery": "^3.1.0",
"laravel-elixir": "^6.0.0-9",
"laravel-elixir-vue-2": "^0.2.0",
"laravel-elixir-webpack-official": "^1.0.2",
"lodash": "^4.16.2",
"vue": "^2.0.1",
"vue-resource": "^1.0.3",
"vuestrap-base-components": "^0.8.10",
"webpack": "^1.14.0"
},
"dependencies": {
"vue-material-datepicker": "^2.0.1"
}
}
my gulpfile.js
const elixir = require('laravel-elixir');
require('laravel-elixir-vue-2');
elixir(mix => {
mix.sass('app.scss')
.webpack('app.js');
});
As the example says on the intro page you have to import them from a subdirectory of the plugin.
The example given on their website is for their toast component which has a default export, however, because wizard is made up of two components it uses named exports instead so the syntax for importing them is slightly different.
Importing default export
import foo from "someComponent"
Importing named exports
import {bar, baz} from "SomeOtherComponent"
So, for your situation you should be able to do:
require('./bootstrap');
import {wizard, wizardStep} from "gritcode-components/src/components/wizard";
const app = new Vue({
el: '#app',
components: {
'vs-wizard': wizard,
'vs-wizard-step': wizardStep
}
});
Hope this helps!
I had a similar issue and this worked for me.
import { wizard as vsWizard } from 'gritcode-components/dist/gritcode-components';
import { wizardStep as vsWizardStep } from 'gritcode-components/dist/gritcode-components';
import { toast as vsToast } from 'gritcode-components/dist/gritcode-components';
note that we are loading this from
"gritcode-components/dist/gritcode-components"
not from
"gritcode-components/src/components/wizard" as suggested in one of the answers.
then in your Vue instance you can do something like this to load the components:
require('./bootstrap');
const app = new Vue({
el: '#app',
components: {
vsWizard,
vsWizardStep,
vsToast
},
data: {
currentStep: 0
},
computed: {
progress: function() {
return {
step1: this.getStepPercentage(1),
step2: this.getStepPercentage(2),
step3: this.getStepPercentage(3)
};
}
},
methods: {
getStepPercentage: function(stepNumber) {
if (stepNumber == 1) {
//depending on your requirements you will return
//a value between 0 and 100 that describe
//the completion status of the step 1
}
if (stepNumber == 2) {
//depending on your requirements you will return
//a value between 0 and 100 that describes
//the completion status of the step 2
}
if (stepNumber == 3) {
//depending on your requirements you will return
//a value between 0 and 100 that describes the
//completion status of the step 3
}
}
}
});
Also in your question, you have two Vue instances: one for which you load the components, and another one bound to the element with id #app. The one with the #app element is the one that will be managing your html from the blade file. The problem you will run into, once this code loads is that you are adding the components on the Vue instance that is not bound to your #app div, and therefore the Vue instance designated for managing your #app element will not have access to them. So I suggest using only one instance of Vue like in the example above unless you have a good reason for using more
Lastly, I would advise you against wrapping your 'vs-wizard' tag element with 'vs-toast', unless you are trying to display the wizard in your toast, which I am not sure is possible.
You can do something like this instead:
<div id="app">
<vs-toast></vs-toast>
<vs-wizard :current-index.sync="currentStep">
<vs-wizard-step
title="Personal Information"
description="Enter your details"
:progress="progress.step1"
icon="person">
</vs-wizard-step>
<vs-wizard-step
title="Payment"
description="Pay with credit card or Paypal"
:progress="progress.step2"
icon="credit-card">
</vs-wizard-step>
<vs-wizard-step
title="Confirmation"
description="Your order details"
:progress="progress.step3"
:disable-previous="true"
icon="check">
</vs-wizard-step>
</vs-wizard>
</div>

Categories

Resources