I have a NextJS App, and inside my page, there are two components.
export default function Home({ user }) {
return (
<>
<Component1 />
<Component2 />
</>
)}
I want to trigger a scroll from Component1 to Component2 by a click on the Component1.
I tried using id on the target, and an anchor on the trigger, it won't work since it's not the same component.
What do you think I am missing?
Related
using styled components' createGlobalStyle as a workaround an issue i've had in my project, whereby I only want the background-color of .application to be white when the following component is rendered. The below implementation gives the perfect outcome however I get a warning in the console saying:
"The component sc-global-hEInDv has been created dynamically.
You may see this warning because you've called styled inside another component.
To resolve this only create new StyledComponents outside of any render method and function component."
Here is the code:
const GlobalStyle = createGlobalStyle`
.application {
background-color: white;
}
`;
return (
<div className={classNames("caseview", className)}>
<GlobalStyle />
<Helmet>
<title>{caseName}</title>
</Helmet>
{caseview.panelLinks.hasItems && (
<CaseViewDetailPanels caseview={caseview} />
)}
<Row>
<Column size={hasTaskGroup ? 9 : 12}>
{caseview.introtext && <FormattedText text={caseview.introtext} />}
</Column>
{hasTaskGroup && (
<Column
as={TaskGroupPanels}
size={3}
taskGroupPanels={caseview.taskGroupCollection}
/>
)}
</Row>
<FormRoute model={caseview} />
</div>
);
Can anyone suggest a workaround to suppress this warning?
You are creating the styled-component inside your functional component. If you move it outside the component, this warning will go away.
Move the below styled component, outside.
const GlobalStyle = createGlobalStyle`
.application {
background-color: white;
}
`;
I'm using Chakra UI in React with Typescript and having such a weird issue I trying to implement Modal with the following code in modal.tsx file.
import {
useDisclosure,
Button,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
ModalFooter,
} from "#chakra-ui/react";
export default function CustomModal() {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<>
<Button onClick={onOpen}>Open Modal</Button>
<Modal closeOnOverlayClick={false} isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Create your account</ModalHeader>
<ModalCloseButton />
<ModalBody pb={6}></ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3}>
Save
</Button>
<Button onClick={onClose}>Cancel</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}
once i click on Open Modal button it simply shows the overlay without actual content of the modal.
I tried to reproduce your problem and found that - For Chakra UI to work correctly, you need to set up the ChakraProvider at the root of your application.
import * as React from "react"
// 1. import `ChakraProvider` component
import { ChakraProvider } from "#chakra-ui/react"
function App({ Component }) {
// 2. Use at the root of your app
return (
<ChakraProvider>
<Component />
</ChakraProvider>
)}
Here is the running code sandbox link of your problem.
In App.js I wrapped the application in <ChakraProvider>.
Hope it works for you.
First Check You Wrappped Your App With ChakraProvider If Provided
I'm new react user, when i see react-router docs, I confused.
let me show,
first, the docs url: https://reacttraining.com/react-router/web/example/route-config
I simplify like this
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
const routes = [
{
path: "/",
component: Sandwiches
},
{
path: "/tacos",
component: Tacos
}
];
export default function RouteConfigExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">/</Link>
</li>
<li>
<Link to="/tacos">tacos</Link>
</li>
</ul>
<Switch>
{routes.map((route, i) => (
<RouteWithSubRoutes key={i} {...route} />
))}
</Switch>
</div>
</Router>
);
}
function RouteWithSubRoutes(route) {
return (
<Route
exact
path={route.path}
component={route.component}
/>
);
}
function Sandwiches() {
return <h2>/</h2>;
}
function Tacos() {
return (
<div>
<h2>Tacos</h2>
</div>
);
}
now, when i click / show /, but click Tacos show nothing.
what expect, click / show /, and click Tacos show Tacos.
I resolve by these
// first, do not use component wrap
export default function RouteConfigExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">/</Link>
</li>
<li>
<Link to="/tacos">tacos</Link>
</li>
</ul>
<Switch>
{routes.map((route, i) => (
<Route
key={i}
exact
path={route.path}
component={route.component}/>
))}
</Switch>
</div>
</Router>
);
}
// second, do not use Switch
export default function RouteConfigExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">/</Link>
</li>
<li>
<Link to="/tacos">tacos</Link>
</li>
</ul>
{routes.map((route, i) => (
<RouteWithSubRoutes key={i} {...route} />
))}
</div>
</Router>
);
}
It bothered me for a long time, now I'm dying to know why, Please tell me in detail, and thanks so much...
In addition, My English is not pretty, understanding...
Switch components only valid children are Route and Redirect, so even though another react component renders a Route it won't work quite in the same way.
Switch children
All children of a <Switch> should be <Route> or <Redirect> elements.
Only the first child to match the current location will be rendered.
Edit
While wrapped Route components can still render, as "grand-children" descendants, it appears that route props are only applied at the root Switch level.
In the following Switch, even though RouteWithSubRoutes specifies the exact prop, RouteWithSubRoutes in the react DOM does not, so only the first element is returned (coincidentally the home "/" route).
<Switch>
{routes.map(route => (
<RouteWithSubRoutes key={route.path} {...route} />
))}
</Switch>
This following Switch is identical to the above except for specifying exact prop, and this works as expected.
<Switch>
{routes.map(route => (
<RouteWithSubRoutes key={route.path} exact {...route} />
))}
</Switch>
/Edit
It sounds like you have a two-part question, why both resolutions work.
The first attempt at fixing by rendering a Route directly succeeds by specifying the exact prop on all routes within the Switch, which only matches and renders the first matching Route or Redirect. When the path is exactly "/" then that component renders, and when it is exactly "/tacos" then that component renders.
The second attempt you render all the routes just right in the Router, which matches and renders all matching routes, but since you specify, again, the exact prop, it matches a single route and works.
Demo
I am learning ReactJS. I would like to display dialog when someone clicks on the icon.
Here is the code:
import React, { Component } from 'react';
import { GridList, GridTile } from 'material-ui/GridList';
import FlatButton from 'material-ui/FlatButton';
import Info from 'material-ui/svg-icons/action/info';
import { fullWhite } from 'material-ui/styles/colors';
import Dialog from 'material-ui/Dialog';
import RaisedButton from 'material-ui/RaisedButton';
(... class stuff, handleClose, handleOpen etc.)
showDialoga() {
const actions = [
<FlatButton
label="Cancel"
primary
onClick={this.handleClose}
/>,
<FlatButton
label="Submit"
primary
keyboardFocused
onClick={this.handleClose}
/>,
];
return (
<div>
<RaisedButton label="Dialog" onClick={this.handleOpen} />
<Dialog
title="Dialog With Actions"
actions={actions}
modal={false}
open={this.state.open}
onRequestClose={this.handleClose}
>
The actions in this window were passed in as an array of React objects.
</Dialog>
</div>
);
}
render() {
console.log(this.props);
return (
<div style={styles.root}>
<GridList
cellHeight={180}
style={styles.gridList}
padding={10}
>
{this.props.movieData.map(tile => (
<GridTile
key={tile.original_image}
title={tile.title}
actionIcon={<FlatButton
icon={<Info color={fullWhite} />}
style={style}
onClick={() => this.showDialoga()}
/>}
>
<img src={tile.original_image} />
</GridTile>
))}
</GridList>
</div>
);
}
}
I am able to pass other function like () => console.log('I am clicked') to onClick although I am not able to pass that showDialoga().
Any idea what is the problem?
I do not believe that's how you are supposed to use dialog.
Instead of passing return of React component on click, try setting the dialog opened state to be true/false. Also do not forget to bind this to the class level if you are using functions to render different components that has event listeners.
Looking at this video the react router seems easy to use, but I can't find how to navigate in my code since I want to link on clicking a div and not use <Link>.
I've search StackOverflow but haven't found any answers that work with 4.0. Trying to import browserHistory gives undefined (before and after installing 'react-router' in addition to 'react-router-dom') from this question:
import { browserHistory } from 'react-router';
console.log('browserHistory:', browserHistory);
I also saw somewhere that there is a 'context' you can get to, but this shows a value for 'match' but not 'context':
<Route path="/" render={({ match, context}) => {
console.log('match:', match);
console.log('context:', context);
Edit
In the dev tools I can see that "Router" has a history property, so when I add that I can get to it:
<Route path="/" render={({ match, context, history}) => {
Is there a way to get to this from outside a route? For example a navbar component that will navigate to other components, but is not inside a Route itself...
If I understand your question, this is how you make a link programaticaly.
class Test extends React.Component {
handleClick() {
console.log(this.context);
this.context.router.history.push('/some/path');
},
render() {
return (
<div onClick={handleClick}>
This is div.
</div>
)
}
}
Test.contextTypes = {
router: React.PropTypes.object.isRequired
}
ReactDOM.render(
<Test />,
document.getElementById("app")
);
Had to read into the docs more. The history object is only passed as a property using the component (or other) attributes on a Route. Apparently need to include the 'history' package and use createBrowserHistory and pass it to the Router, then specify the component in a Route. I think this should work fine since exact isn't specified...
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
ReactDOM.render( (
<Router history={ history }>
<Route path="/" component={ App } />
</Router>
),
document.getElementById('root')
);
Before I just had <App/> inside <Router> and didn't have access to those properties.
Why don't you just wrap your div in the link instead of trying to circumvent it and make your life easier?
<Link to="/" >
<div className="to-component">go to component</div>
</Link>