I need help.
If I use JSON.stringify(window.location.href), is there any way to show that URL without "" (quotes / as a string)? So showing it like a link and not a string.
If not... Is there a way to use window.location.href in React without having to use JSON.stringify()?
Or maybe use something to replace window.location.href but same result?
Basically need to show / use that url as a link (html < a > tag) not as a string.
New images!
--- Ignore the key: URL_HREF its MY_URL instead ---
Any help is appreciated!
CodePudding user response:
This seems to do what you're asking.
class SimpleExample extends React.Component {
render() {
return (
<div>
<a href={`${window.location.href}`}> Link </a>
</div>
);
}
}
ReactDOM.render(<SimpleExample />, document.getElementById('example'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.2/umd/react-dom.production.min.js"></script>
<div id="example"></div>
EDIT:
But I'm also curious why <a href={window.location.href}> Link </a>
doesn't work.
CodePudding user response:
The problem seems to be with your custom hook. Here's a variation that should work:
If you aren't using or can't use TypeScript in your React project, you can navigate to the playground link above and copy the transpiled JavaScript code (it's on the right side of the page).
import {
default as React,
useCallback,
useEffect,
useState,
type Dispatch,
type SetStateAction,
} from 'react';
// useLSState: This is a modified version of your "useStickyState"
export type Result <T = void, E extends Error = Error> = T | E;
export function getError (exception: unknown): Error {
return exception instanceof Error ? exception : new Error(String(exception));
}
export type Json = boolean | null | number | string | Json[] | { [key: string]: Json };
export type JsonValidator = (data: Json) => boolean;
export function safeParse <T extends Json = Json>(json: string, validate: JsonValidator = () => true): Result<T> {
try {
const data = JSON.parse(json) as T;
if (validate(data)) return data;
throw new Error('Parsed JSON failed validation');
}
catch (ex) { return getError(ex); }
}
export function safeLSGet <T extends Json = Json>(key: string, validate: JsonValidator = () => true): Result<T> {
const json = localStorage.getItem(key) ?? new Error(`localStorage item at "${key}" was null`);
return json instanceof Error ? json : safeParse(json, validate);
}
export function safeLSSet <T extends Json = Json>(key: string, value: T): Result {
try {
const json = JSON.stringify(value);
localStorage.setItem(key, json);
}
catch (ex) { return getError(ex); }
}
export function useLSState <T extends Json>(
initalState: T,
key: string,
validate?: JsonValidator,
): [state: T, setState: Dispatch<SetStateAction<T>>] {
const [value, setValue] = useState(initalState);
useEffect(() => {
const parsed = safeLSGet<T>(key, validate);
if (parsed instanceof Error) {/* the localStorage value was null */}
else setValue(parsed);
}, [key, validate]);
const setLSValue = useCallback<Dispatch<SetStateAction<T>>>(action => {
if (typeof action === 'function') {
setValue(prev => {
const value = action(prev);
const err = safeLSSet(key, value); // potentially useful for debugging
return value;
});
return;
}
const value = action;
setValue(value);
const err = safeLSSet(key, value); // potentially useful for debugging
}, [key, setValue]);
return [value, setLSValue];
}
// Example usage:
const lsKey = 'MY_URL';
function Example (props: { item_url: string }) {
const [previouslyClickedUrl, setPreviouslyClickedUrl] = useLSState(window.location.href, lsKey);
const handleClick: React.MouseEventHandler<HTMLAnchorElement> = ev => {
// Prevent native navigation on click
ev.preventDefault();
// Update the localStorage item
setPreviouslyClickedUrl(window.location.href);
// Navigate to the new URL
window.location.href = props.item_url;
};
return (
<div>
<div>Previous URL: {previouslyClickedUrl}</div>
<a
href={props.item_url}
onClick={handleClick}
>{props.item_url}</a>
</div>
);
}