Trouble making stateful React components work together - javascript

I'm making a React App and i'm struggling to get the basic functionality of components with state working. So far i've got a home page that connects to a registration page, when I click to the registration page I can handle user input. The registration is the class component I am trying to use state in so far.
I've set up a pretty basic process so far in this component just to see if it works. But when I click the button to console log what is currently stored the entire page reloads as if nothing has happened.
A very basic display of what it currently looks like:
import registerUser from './user.js';
class App extends Component {
render() {
return (
<Router>
<Route path='/register' component={registerUser}/>
</Router>
)
}
}
export default App;
class registerUser extends Component {
handleChange = () => {
console.log('test');
}
render() {
return (
<div>
<button onClick={this.handleChange}>Click</button>
</div>
)
}
export default registerUser;
But as I mentioned when I click the button the entire page just reloads as if nothing has occured. Am I missing something something basic as to why trying to use this method in a separate component reloads the entire app?
Any help would be greatly appreciated.

If the button is inside a form, then you must write e.preventDefault() in your handleChange function,
handleChange = (e) => {
e.preventDefault(); //It will prevent form submit
console.log('test');
}
Demo
Note: React component name should be in PascalCase, so just replace registerUser to RegisterUser.

Related

In React how to stop rendering components which state or props not changed?

I got an issue in my project , that I had a main component which acts as the parent component of my project inside that I had the routes for the other components and some other component which are directly imported into it like a Side Navbar Component and Login Component so which are triggered on an event button click , but when I open those components all the other components are re-rendering .
export const AppFramework = (props) => {
const [isOpen, setIsOpen] = useState(false);
const [isSideNav, setIsSideNav] = useState(false);
const OptimizedRoutes = React.memo(AppRoutes);
useEffect(() => {
console.log('AppFramework Mounted');
}, []);
// Methods For Opening and closing of Login and SideNav
const handleOpen = useCallback(() => {
setIsOpen(true);
}, [isOpen]);
const handleClose = useCallback(() => {
setIsOpen(false);
}, [isOpen]);
const openSideNav = useCallback(() => {
return setIsSideNav(true);
}, [isSideNav]);
const LoginPopBody = (
<div className="pop-window">
<Button startIcon={<Close />} onClick={handleClose}></Button>
{/* {For Fields for loggin in .........} */}
</div>
);
return (
<Router>
<HideOnScroll>
<AppBar color="default" className="app-header">
<Button startIcon={<Menu />} onClick={openSideNav}></Button> // Button To Open Side Navbar
<Button onClick={handleOpen}>Login</Button> /* Button To Open Login Popup */
</AppBar>
</HideOnScroll>
//sidenav comp passing props to open and close below
<SideNav open={isSideNav} close={setIsSideNav} />
//routes are below
<main className="main-blk">
<Suspense fallback={<div>Loading...</div>}>
<OptimizedRoutes />
</Suspense>
</main>
<Modal open={handleOpen}>{LoginPopBody} </Modal>
</Router>
);
};
export default React.memo(AppFramework);
On opening and closing of both login popup and side navbar renders every component .I tried React.memo in each component but nothing happened , I hope hooks will give a solution for this.
And one more thing while entering each input on login popup form fields also renders every components behind the login popup . what will be the solution for these issues ?
This might not be the answer you are satisfied with but most of the time these problems pop up because of the way you design/construct your components. In react planning the components is the first and in my opinion the most important thing. It can save us from a lot of trouble. In this case You need to keep the components linked but independent of each other.
I would recommend you to read https://reactjs.org/docs/thinking-in-react.html. This might help you.
Changing the state will definitely re-render the whole component. But to avoid some components to stop re-rendering or re-render on come custom state changes you can use useCallBack hook.
The following article might help.
https://kentcdodds.com/blog/usememo-and-usecallback/
You can put the other component in individual functions and use useCallback hook on those function. This way you can define on which state change should those functions be used again.
Actually the issue is resolved , actually my problem is very simple , its not a complicated problem , To open the Side Navbar and Login Component I don't need to pass a boolean value from the parent component as a Prop .
Instead of that, we can get the boolean value from the own component by a passing a boolean value to the module to be shown in my case I used Material UI's Modal and Drawer by an event like button click or any other event .
This is what I did to solve my issue . In short I made the components independent.

Send event to another class

in my web react project i have two class one "Menu" return the Menu for my dashboard (the links to change the pages "Home" , "messages" ....) and another one "Box" for show the pages (it's the container of my website pages ) so my question is how the page when i click button ?.
class menu(){
render(){
return(<button>click to go to home</button>) ;
}
}
class box(){
render (){
return(<Home>this is the home</Home>) ;
} }
You can create a parent component that has the page property and the setPage method.
Inside that component, render the toolbar and the pages. The toolbar should accept a prop that'll called onClickPage that should dispatch the setPage. For example:
const [page, setPage] = React.useState("dashboard");
....
<Toolbar onClickPage={page => setPage(page)} />
<Pages page={page} />
This is what's called Lifting the state up (https://reactjs.org/docs/lifting-state-up.html) I suggest you to read their docs. It's very beginners friendly.
If your main problem is to navigate between pages you can easily achieve this by using react-router.
https://reactrouter.com

How to make a button redirect to another page in React

I have a component which has in its Class.propTypes a function onClick: onClick: PropTypes.func
In another component I'm using this component multiple times to populate a page. Each of these components have a title which when clicked should redirect to another page.
The problem I have is that it doesn't work when I click on it. It does nothing.
This is the render of the main component:
render() {
return (
<Class
title={account.AccountName}
onClick={() => "mySite/accountview?id=" + account.AccountName}
>
</Class>
...
);
}
What should I add to onClick to make it work?
You need use React Router.
With Link:
<Link to={`/mySite/accountview?id=${account.AccountName}`}>something</Link>
With onClick:
<button onClick={() => hashHistory.push(`/mySite/accountview?id=${account.AccountName}`)}></button>
You can use hashHistory or browserHistory :D

Prevent component from unmounting - showing notification to users before opening other component

In my web app there is a form where users put in data. If they want to navigate to other component or back, I want to notify them that changes were made to form and show them confirmation dialog.
I know how to implement this if users click on back button on top of the form, but don't have any idea how to handle it when users click on sidebar menu options. (there is a sidebar with multiple links to other components - using react-router).
I have tried something using componentWillunmount() but no luck since component gets unmounted in any case.
If anyone has experience in this I would really need some help.
Try the routerWillLeave hook, here is a example from react-router's documentation:
const Home = withRouter(
React.createClass({
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave)
},
routerWillLeave(nextLocation) {
// return false to prevent a transition w/o prompting the user,
// or return a string to allow the user to decide:
if (!this.state.isSaved)
return 'Your work is not saved! Are you sure you want to leave?'
},
// ...
})
)
https://github.com/ReactTraining/react-router/blob/master/docs/guides/ConfirmingNavigation.md

Proper way to set state between two react components

I have a component for a Navbar and a component for a Sidebar. The sidebar component has a state variable that decides whether or not it should be open. Here is what I have.
export default class Sidebar extends Component {
constructor() {
super(...arguments);
this.state = { open: false };
}
toggle() {
this.setState({ open: !this.state.open });
}
render() {
return (
<LeftNav open={this.state.open}>
<MenuItem
onClick={this.toggle.bind(this)}
primaryText="Close"
leftIcon={<CloseIcon/>}
/>
</LeftNav>
)
}
}
The problem I am having is in accessing the toggle functionality from a separate component, the Navbar.
<AppBar
title="Navbar"
iconElementLeft={
<IconButton onClick={}> // want to enable clicking here to close sidebar component
<MenuIcon>
</IconButton>
}
/>
What I am wondering is, what is the best practice to set the state of separate components?
You have entered into the exciting realm of "data flow".
One way to implement this is to have some sort of centralized object that listens for events and dispatches information to other components. In other words, your NavBar handler can dispatch what many frameworks refer to as an "action" with some information, and then other components can re-render based on the information from that event.
A library that's gaining some popularity is redux if you're into a pre-packaged solution for this kind of thing. If nothing else, it'll help you gain some insight into how other people are currently doing this type of thing.

Categories

Resources