React Link to open new tab - javascript

I Have a React link in my material table.
actions={[
rowData => ({
icon: () => <Link style={{ fontSize:"15px" ,fontSize:'15px'}} to={{pathname:'/VV',state: rowData }} >View</Link> ,
onClick: (rowData)
})
]}
I want to be able to open a new tab on the click.
But my child objects keep getting Cannot read properties of undefined when i decide to open it in a new tab
Please can i have some assistance i've been stuck on this problem.

There is a simple way you can do that without React-Router library,
Make a Link component like blow and use it.
const Link = () => {
const linkRef = useRef(null)
const handleClick = () => {
linkRef.current.link.click()
}
return (
<div ref={linkRef} onClick={handleClick}>
Go to google!
</div>
)
}
You can put the link you want in href and render the Link component where you want! also you can give it a style you want cuz it's a component! :D
I hope you find an answer!

Related

How to render a new popup every time I clicked Grid?

The problem is...
The first popup renders fine.
But when I try to render the second popup, it's not working.
A new popup is not invoked, the previous popup is refreshed.
I want to call a new popup when I clicked a cell in the grid.
my code is like this
const Main = () => {
const [isPopupOpen, setIsPopupOpen] = useState(false);
return (
<>
... other components (including grid)
{ isPopupOpen && <Popup />}
</>
)
};
when Grid is Clicked, 'isPopupOpen' is updated to true.
I use 'react-new-window' library, and this library use 'window.open()' ((https://github.com/rmariuzzo/react-new-window)
so I set different window names to call several popups.
but I can't solve the problem.
I try to set a state object that has a boolean value.
const [popupObj, setPopupObj] = useState({});
when the grid is clicked, popupObj updates like
{'cellA': true, 'cellD': true}
and a return statement is like
{popupObj[cellName] && <Popup /> }
but the result was the same.
what should I do to solve this problem?
I wrote an example for you. Hope it helps.
use popupIds state to store the popups that you want to open
use Set to toggle the popupIds in the addPopup click handler
import * as React from "react";
export default function App() {
const [popupIds, setPopupIds] = React.useState([]);
const addPopup = (popupId) => {
const set = new Set(popupIds);
if (set.has(popupId)) {
set.delete(popupId);
} else {
set.add(popupId);
}
setPopupIds(Array.from(set));
};
return (
<div className="App">
{["hello", "react"].map((popupId) => (
<div onClick={() => addPopup(popupId)}>{popupId}</div>
))}
{popupIds.map((popupId) => (
<Popup title={getPopupTitle(popupId)} />
))}
</div>
);
}
const getPopupTitle = (popupId) => `title for ${popupId}`;
const Popup = ({ title }) => <div>{title}</div>;
Here is a codesandbox that you can play with directly.
You need to add your popup in an array, so you can render many popup as you want, then you need to define in How much time you will remove a added popup from array or add a close button
Extra: you can configure in global state to access in all your application to your popups and you will have a component like this: https://www.npmjs.com/package/notistack

How to handle React props correctly

I posted this here because I am relatively new to React and didn't know what exactly should I google. In my React project, I have a kendo grid that has a custom column named OPTIONS, like this:
<Grid onDataStateChange={onDataStateChange}
data={result}
{...{skip:0, take:13}}>
<GridColumn cell={CommandCell} title="Options"/>
<GridColumn field="session_id" title="Session" filter='text'/>
<GridColumn field="sn_zag_id" title="Service" filter='text'/>
The Option column is defined like this:
const [visible2, setVisible2] = useState(false);
const [snZagId, setSnZagId] = useState();
const toggleDialogPrilog = (props) => {
setVisible2(!visible2);
setSnZagId(props.dataItem.sn_zag_id)
}
const CommandCell = (props) => <Options {...props}/>
const Options= (props) => {
return <td className="k-command-cell">
<div style={{marginTop:'2%'}}>
<Button style={{width:'8vw',marginTop:'2%'}}
onClick={()=>toggleDialogPrilog(props)}>
Add
</Button></>}
</div>
{ visible2 &&
<Dialog onClose={()=> toggleDialogPrilog()} title={"Add"} style={{width:'50%'}}>
<Prilog snZagId={snZagId}/>
</Dialog>
}
</td>;}
So, In the option column I have a button ADD that, when it's clicked, opens a Dialog with PRILOG component inside it. The grid that I am talking about is big, made up of pages of 13 rows. Everything works perfectly, so when I click on the Add button, the dialog is open with custom material for that row. But the thing is, if I open the console/inspect, I can see that when I click add, 13 dialogs are open at the same time:
I am aware to some point that when I click Add, all dialogs are rendered bcz I send props, but I don't know how to stop it. In other words, how can I modify my code so that only one(1) dialog opens when I click Add?
I managed to solve the problem somehow, but I don't know what exactly is the difference. Instead of putting the Options component in the same jsx file, I made another component named SessionOptions like this:
Session.jsx:
import SessionOptions from '../../Popup/SesijaOpcije';
...
const CommandCell = (props) => <SessionOptions props={props}/>;
...
SessionOptions.jsx:
...
export default function SessionOptions({props}) {
...
return <td className="k-command-cell">
<div style={{marginTop:'2%'}}>
<Button style={{width:'8vw',marginTop:'2%'}}
onClick={()=>toggleDialogPrilog(props)}>
Add
</Button></>}
</div>
{ visible2 &&
<Dialog onClose={()=> toggleDialogPrilog()} title={"Add"} style={{width:'50%'}}>
<Prilog snZagId={snZagId}/>
</Dialog>
}
</td>;}
And now it opens just one dialog. The only difference that I clearly see is in sending the props
//Before:
const CommandCell = (props) => <Options {...props}/>
//After:
const CommandCell = (props) => <SessionOptions props={props}/>;
The first one is property spread notation, and the second one is...? Can anybody explain the difference.
If anybody could clearify more.

React: useState not preserving updated state upon click

Update: I was truly trying to reinvent the wheel here, the code below works if you use it in conjunction with React's Link or NavLink instead of anchor tags, it has built-in listening functionality that will keep track of the page you are currently on and pass along the updated state accordingly as your route changes to a different page.Thank you to everyone that chimed in and pointed me in the right direction!
I'm still fresh off the block with React, especially with hooks, but what I'm trying to accomplish is to trigger the 'active' tab class of my navbar elements through conditional rendering and managing state with useState.
However, when I call 'setActiveTabIdx' upon click, I can't tell if it's not updating state at all, or if it is and is resetting to the default value upon re-render. I was trying to use my dev tools to monitor upon click but it's happening too fast for me to say one way or the other. I've messed around a fair bit at this point trying a number of different things if anyone would be willing to take a look, thanks!
const NavBar = () => {
const [activeTabIdx, setActiveTabIdx] = useState(0)
const navItems = ['About', 'Services', 'Oils', 'New Patients', 'Courses', 'Recommendations', 'Contact' ]
const renderedItems = navItems.map((nav, idx) => {
const active = idx === activeTabIdx ? 'active' : ''
return (
<a
onClick={() => setActiveTabIdx(idx)}
href={`${nav.split(' ').join('').toLowerCase()}`}
className={`${active} item`}
key={idx}
>{nav}</a>
)
})
return (
<div className="ui tabular menu">
{renderedItems}
</div>
);
};
export default NavBar;
You are trying to change state (which is done) and then redirect user to other page (which is also done). The state resets after redirection.
It seems it is resetting, I added this block to check:
const NavBar = () => {
const [activeTabIdx, setActiveTabIdx] = useState(0)
const navItems = ['About', 'Services', 'Oils', 'New Patients', 'Courses', 'Recommendations', 'Contact' ]
// --------- Start block ---------
useEffect(() => {
console.log(`current state: ${activeTabIdx}`);
}, [activeTabIdx]);
// --------- End block ---------
const renderedItems = navItems.map((nav, idx) => {
const active = idx === activeTabIdx ? 'active' : ''
return (
<a
onClick={() => setActiveTabIdx(idx)}
href={`${nav.split(' ').join('').toLowerCase()}`}
className={`${active} item`}
key={idx}
>{nav}</a>
)
})
return (
<div className="ui tabular menu">
{renderedItems}
</div>
);
};
export default NavBar;
And to check codesandbox

Is it possible to pass multiple functions to navigation items?

I'm quite new to React.js and I need to add a logout link to a hamburger menu. In the parent component there is already defined an onClick -function for all the NavLinks, but I have the new logout button there which needs to be passed the logout-function instead. I'm not quite sure how to achieve that. I've tried several approaches that came to my mind, but they either were fired immediately when the nav was loaded or crashed the component.
The Nav is a an array of objects. A couple of NavLink items are visible only on mobile sizes and that part I got working already, but how to make the log out link work only when clicking that specific item?
Any help is appreciated.
return (
<li className={liClassnames}>
<OTNavLink
activeClassName="is-active"
disabled={disabled}
link={link}
isExternal={isExternal}
to={link}
className={linkClassNames}
/*onClick={(e) => { // This code was here originally
toggleNavigation(e);
}}*/
onClick={(e) => { // And this is how I last tested whether altering this
SessionUtils.logout(e); // changes the links behaviour
}} // it naturally did for all the links
{...linkAttributes}
>
Here is the OTNavLink -components code you asked :)
const OTNavLink = (props) => {
let {link, isExternal = false, disabled, children, ...rest} = props;
let restForAnchor = omit(rest,["activeClassName", "disabled", "to"]);
if (disabled) {
return (
<a {...restForAnchor}>
{children}
</a>
)
}
// unwrap link (this should be unnecessary but applies to some cases)
let _link = isEmpty(link) ? "javascript:void();" : isFunction(link) ? link() : link;
if (isExternal) {
return (
<a
href={_link}
{...restForAnchor}
>
{children}
</a>
)
} else {
return (
<NavLink
to={_link}
{...rest}
>
{children}
</NavLink>
)
}
};
And here's an example of the NavigationItems array:
It consists of multiple similar objects. some are rendered on mobile and hidden in desktop.
let navigationItems = [
{
message: "navigation.timeline",
disabled: false,
icon: {
type:"custom",
name:"my-name"
},
link: "/timeline",
key: "timeline"
},
How can I pass a different function call to that one last logout link?
If you need any more details let me know :)
I think I managed a solution myself in the end. It was so simple all along. Although someone can tell me if there is a better way. :)
I just made a ternary check in the custom component, so it will apply to only the links that have that message property.
onClick={this.props.message === 'logout' ? (e) => SessionUtils.logout(e) : (e) => {
toggleNavigation(e);
}}

Change react.js(multi page app) with button element?

beginner with react.js. My goal is to switch pages in my app. I have made this component for export into another:
const component = ({ name, email, id }) => {
return (
<button href="secondContent.html" onclick="secondContent()" id="component">
<div>
header
</div>
</button>
);
}
Function of this button was meant to be a switcher to second page (secondComponent).
I also have been trying to deal with html page to (actually) create that secondComponent file.
After trying to switch by this button for a few times, I could not get a result which I wanted.
If annyone can brief me with a proper way to solowe this problem and sugest me a better solution, pls help.
Thanks in advance. :)
There are a number of ways this can be achieved however for a simple sitatuion like this, you could do something like:
const component = ({name, email, id}) => {
const gotoSecondContent = () => {
window.location = "secondContent.html";
}
return (
<button onclick={ gotoSecondContent } id="component">
<div>header</div>
</button>);
}
You should check the react-router-dom documentation. I think you will find all you need there !
https://reacttraining.com/react-router/web/guides/philosophy

Categories

Resources