I want to make when i click button, show modal in different class.
how to make it this?
import React, { Component } from 'react';
import addmodal from './addmodal';
class page extends Component {
...//skip
handleAdd= () =>{
//...how?
}
render(){
return (
<button onClick={this.handleAdd} > Add </button>
)
}
}
import React, { Component } from 'react';
class addmodal extends Component {
// ... skip
render(){
return(
<modal inOpen={this.state.isopen} >
...//skip
</modal>
)
}
}
export default addmodal;
I can't call this addmodal...
how to call modal?
First, your variable naming is terrible. I fixed it for you here. The state that dictates if modal is open must be on the parent component since you have your trigger there. Then, pass it as props to the modal component. Here is the fixed code for you:
import React, { Component } from 'react';
import AddModal from './addmodal';
class Page extends Component {
constructor(){
super();
this.state = { isModalOpen: false };
}
...//skip
handleAdd= () =>{
this.setState({ isModalOpen: true });
}
render(){
return (
<div>
<button onClick={this.handleAdd} > Add </button>
<AddModal isOpen={this.state.isModalOpen} />
</div>
)
}
}
import React, { Component } from 'react';
class AddModal extends Component {
// ... skip
render(){
return(
<modal inOpen={this.props.isOpen} >
...//skip
</modal>
)
}
}
export default AddModal;
what about using trigger. Its very usefull.
<Modal trigger={ <button onClick={() => onCLickPay()} className={someting}> When clicked here modal with show up</button> }`enter code here` >
Related
import React from 'react';
import reactDom from 'react-dom';
class Second extends React.Component {
showText= alert ("Got it");
render () {
return (
<div>
<button onClick ={ showText }> Click Me </button>
</div>
);
}
}
export default Second;
I am trying to make an onclick button but it keeps saying showTest is undefined
You need to use the this keyword as you are refering to an object of the class.
onClick ={ this.showText }>
import React from 'react';
class Second extends React.Component {
showText = () => alert ("Got it");
render () {
return (
<div>
<button onClick ={this.showText}> Click Me </button>
</div>
);
}
}
export default Second;
I have a Button.js component and I am using it on multiple locations on my app. How can I add the button value such as <button>hello world</button> when I am importing it on my Dashboard.js component?
Button.js
import React, { Component } from "react";
import './Button.css'
class Button extends Component {
render() {
return (
<button></button>
);
}
}
export default Button;
Dashboard.js
import React, { Component, useMemo, useState } from "react";
import Button from "../Button/Button";
import SearchBox from "../SearchBox/SearchBox";
import "./Dashboard.css";
import fire from "../../fire";
import UserList from "./UserList";
class Dashboard extends Component {
render() {
return (
<div>
<Button/>
</div>
);
}
}
export default Dashboard;
You can pass a value to Button component in two ways
export default class Dashboard extends React.Component {
render() {
return (
<div>
<Button>Hello world</Button>
</div>
);
}
}
class Button extends React.Component {
render() {
return (
<button>{this.props.children}</button>
);
}
}
or
export default class Dashboard extends React.Component {
render() {
return (
<div>
<Button value="hello world"/>
</div>
);
}
}
class Button extends React.Component {
render() {
return (
<button>{this.props.value}</button>
);
}
}
Pass the value in as a prop.
In the Dashboard component:
class Dashboard extends Component {
render() {
return (
<div>
<Button value="hello world"/>
</div>
);
}
}
In the button component:
class Button extends Component {
render() {
return (
<button>{this.props.value}</button>
);
}
}
send text via props
Button.js
class Button extends Component {
render() {
return (
<button>{this.props.text}</button>
);
}
}
Dashboard.js
class Dashboard extends Component {
render() {
return (
<div>
<Button text={'Here is your custom text'}/>
</div>
);
}
}
class Button extends Component {
constructor(props: any) {
super(props);
}
render() {
return (
<button>
{this.props.children}
</button>
);
}
}
class Dashboard extends Component {
render() {
return (
<div>
<Button>
hello world
</Button>
</div>
);
}
}
I am using bootstrap modal and on click event on an element its opened but cant closed it when i click the "x" on the right corner of the modal.
The problem is that i do succeed to pass the state by props from parent to child but when i invoke the function "lgClose" inside the child, its goes to the parent component but doesnt actually changing the state position to "false".
I can see its go inside the function because i put "console.log('im in the function')" and i can see it. Why the state doesnt changed to false in parent component ?
import React, { Component } from 'react';
import { Link } from 'react-router-dom'
import { connect } from 'react-redux';
import { getAllUsers,getMessages } from './../actions';
import { bindActionCreators} from 'redux';
import { Button, Modal } from 'react-bootstrap';
import ContainerModal from './../components/popup_modal';
// parent component
class MainContainer extends Component {
constructor(props, context) {
super(props, context);
this.state = {
lgShow: false
};
}
componentWillMount(){
this.props.getAllUsers();
}
renderList = ({list}) => {
if(list){
return list.map((item)=>{
return(
<div key={item._id} className="item-list" onClick={() => this.setState({lgShow: true})}>
<div className="title">{item.firstName} {item.lastName}</div>
<div className="body">{item.age}</div>
<div>
<ContainerModal lgShow={this.state.lgShow} lgClose={this.lgClose}/>
</div>
</div>
)
})
}
}
lgClose = () => {
this.setState({lgShow:false});
console.log('im in the function');
}
render() {
console.log(this.state);
return (
<div className="App">
<div className="top">
<h3>Messages</h3>
<Link to="/form">Add</Link>
</div>
<div className="messages_container">
{this.renderList(this.props.users)}
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
messages:state.messages,
users:state.users
}
}
function mapDispatchToProps (dispatch) {
return bindActionCreators({getAllUsers,getMessages},dispatch);
}
export default connect(mapStateToProps,mapDispatchToProps)(MainContainer);
import React from 'react';
import { Button, Modal } from 'react-bootstrap';
// child component
const ContainerModal = (props) => {
return (
<div>
<Modal
size="lg"
show={props.lgShow}
onHide={ props.lgClose }
aria-labelledby="example-modal-sizes-title-lg"
>
<Modal.Header closeButton>
<Modal.Title id="example-modal-sizes-title-lg">
Large Modal
</Modal.Title>
</Modal.Header>
<Modal.Body>item</Modal.Body>
</Modal>
</div>
)
}
export default ContainerModal;
Seems that this in the lgClose function is not pointing to MainContainer.
If that is the case, one way of solving it is to bind the lgClosefunction to MainContainer in the constructor:
constructor(props, context) {
super(props, context);
this.state = {
lgShow: false
};
this.lgClose = this.lgClose.bind(this); // Add this line
}
Hope this helps :)
In your ContainerModal try this:
import React from 'react';
import { Button, Modal } from 'react-bootstrap';
// child component
const ContainerModal = (props) => {
return (
<div>
<Modal
{...props}
size="lg"
aria-labelledby="example-modal-sizes-title-lg"
>
<Modal.Header closeButton>
<Modal.Title id="example-modal-sizes-title-lg">
Large Modal
</Modal.Title>
</Modal.Header>
<Modal.Body>item</Modal.Body>
</Modal>
</div>
)
}
export default ContainerModal;
And in renderList, do this:
<ContainerModal show={this.state.lgShow} onHide={this.lgClose} />
Here is the reason why your lgShow remains true.
This explanation would be little longer. So please bear with me.
Here is what you have done.
You have added your ContainerModal as a child of div (className="item-list") inside renderList method which has an onClick listener attached to itself.
When you click on the list item it works fine and the modal appears but when you click on the close button on the modal things become fishy.
This is because of the onClick listener of the div (className="item-list") getting called after the
ContainerModal's click listener is called setting the lgShow to true again. This behavior is termed as event bubbling where both parent and child receive event in a bottom-up way (i.e child receiving the first event followed by the parent).
To verify this behavior add a console.log to the onClick listener of the div.
Here is a link to a github question for the explanation on event bubbling
Solution
First and foremost suggestion would be to take out the ContainerModal from the renderList method to the root div. This is because right now for every list item of yours a ContainerModal is being created which is unnecessary. For example if you have 10 users in the list you are creating 10 ContainerModal (To verify this increase the number of users and you could see the shade of the modal getting darker.)
The solution to the above problem is to take the ContainerModal to the root level where it's onClick will not coincide with the onClick of the div (className="item-list") in the renderList and your problem would be solved.
Here is the modified solution.
import React, { Component } from 'react';
import { Link } from 'react-router-dom'
import { connect } from 'react-redux';
import { getAllUsers,getMessages } from './../actions';
import { bindActionCreators} from 'redux';
import { Button, Modal } from 'react-bootstrap';
import ContainerModal from './../components/popup_modal';
// parent component
class MainContainer extends Component {
constructor(props, context) {
super(props, context);
this.state = {
lgShow: false
};
}
componentWillMount(){
this.props.getAllUsers();
}
renderList = ({list}) => {
if(list){
return list.map((item)=>{
return(
<div key={item._id} className="item-list" onClick={() => this.setState({lgShow: true})}>
<div className="title">{item.firstName} {item.lastName}</div>
<div className="body">{item.age}</div>
<div>
{/* <ContainerModal lgShow={this.state.lgShow} lgClose={this.lgClose}/> */}
</div>
</div>
)
})
}
}
lgClose = () => {
this.setState({lgShow:false});
console.log('im in the function');
}
render() {
console.log(this.state);
return (
<div className="App">
<div className="top">
<h3>Messages</h3>
<Link to="/form">Add</Link>
</div>
<div className="messages_container">
{this.renderList(this.props.users)}
</div>
<ContainerModal lgShow={this.state.lgShow} lgClose={this.lgClose}/>
</div>
);
}
}
function mapStateToProps(state) {
return {
messages:state.messages,
users:state.users
}
}
function mapDispatchToProps (dispatch) {
return bindActionCreators({getAllUsers,getMessages},dispatch);
}
export default connect(mapStateToProps,mapDispatchToProps)(MainContainer);
import React from 'react';
import { Button, Modal } from 'react-bootstrap';
// child component
const ContainerModal = (props) => {
return (
<div>
<Modal
size="lg"
show={props.lgShow}
onHide={ props.lgClose }
aria-labelledby="example-modal-sizes-title-lg"
>
<Modal.Header closeButton>
<Modal.Title id="example-modal-sizes-title-lg">
Large Modal
</Modal.Title>
</Modal.Header>
<Modal.Body>item</Modal.Body>
</Modal>
</div>
)
}
export default ContainerModal;
Look out for the changed position of Container Modal. Rest of the code is fine.
I have also uploaded a working solution to code sandbox. Have a look at it.
Hope this helps.
So, I try to understand how can I make right redirection in my app with event clicks? I put the react-router-dom redirect logic into the button event handler, but it does not work.
What is I'm making wrong?
import React, { Component, Fragment } from 'react';
import Preloader from '../Preloader/Preloader'
import preloaderRunner from '../../Modules/PreloaderRunner'
import { Redirect } from 'react-router-dom';
import axios from 'axios';
class LoginPage extends Component {
constructor(props) {
super(props);
this.state = {
navigate: false
}
}
handleClick = () => {
console.log('Button is cliked!');
return <Redirect to="/employers" />
}
render() {
return (
<Fragment>
<Preloader/>
<h1>This is the Auth Page!</h1>
{this.state.navigate === true
? <div>
<div>You already loggined!</div>
<button onClick={this.handleClick}>Go to the Employers List!</button>
</div>
: <div>
<form>
// some code...
</form>
</div>}
</Fragment>
)
}
}
export default LoginPage;
Things returned by a click handler will not be rendered by your component. You have to introduce a new state property that you can set and then render the <Redirect> component when that property contains a path to redirect to:
class LoginPage extends Component {
constructor(props) {
super(props);
this.state = {
navigate: false,
referrer: null,
};
}
handleClick = () => {
console.log('Button is cliked!');
this.setState({referrer: '/employers'});
}
render() {
const {referrer} = this.state;
if (referrer) return <Redirect to={referrer} />;
// ...
}
}
Alternatively instead of rendering your own button with a click handler you could render a <Link> component as suggested by #alowsarwar that will do the redirect for you when clicked.
I believe on click you want to take the user to '/employers' . Then you need to use Link from the react-router-com. Ideally in React events like 'handleClick' should change the state not return a JSX (this is the wrong approach)
import React, { Component, Fragment } from 'react';
import Preloader from '../Preloader/Preloader'
import preloaderRunner from '../../Modules/PreloaderRunner'
import { Redirect, Link } from 'react-router-dom';
import axios from 'axios';
class LoginPage extends Component {
constructor(props) {
super(props);
this.state = {
navigate: false
}
}
handleClick = () => {
this.setState({ navigate: true});
}
render() {
return (
<Fragment>
<Preloader/>
<h1>This is the Auth Page!</h1>
{this.state.navigate === true
? <div>
<div onClick="this.handleClick">If you want to enable link on some event (Sample test case fyr)</div>
{this.state.navigate ? <Link to='/employers'/> : null}
</div>
: <div>
<form>
// some code...
</form>
</div>}
</Fragment>
)
}
}
export default LoginPage;
How to implement a React component with a similar structure of react-bootstrap Modal?
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
<h1>My Body</h1>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.handleClose}>Close</Button>
</Modal.Footer>
</Modal>
I was working a solution like this:
import React, { Component } from 'react'
import CardHeader from './CardHeader.jsx'
import CardBody from './CardBody.jsx'
import CardFooter from './CardFooter.jsx'
class Card extends Component {
render() {
return (
<div>
{this.Header}
{this.Body}
{this.Footer}
</div>
)
}
}
Card.Header = CardHeader
Card.Body = CardBody
Card.Footer = CardFooter
export default Card
Sub-components(all are equals) and receive a text prop to render:
import React, { Component } from 'react'
export default class CardHeader extends Component {
render() {
return (
<div>
{this.props.text}
</div>
)
}
}
And calling them:
<Card>
<Card.Header text='Header'/>
<Card.Body text='Body'/>
<Card.Footer text='Footer'/>
</Card>
But didn't work!
Effectively what you are doing is just rendering the children of the parent component.
So if you just change your Card component to...
import React, { Component } from 'react'
class Card extends Component {
render() {
return (
<div>
{this.props.children}
</div>
)
}
}
export default Card
It will then render anything that you pass into the component.
For exporting and being able to use Card.Header etc... you can create a new const
const card = {
Header: HeaderComponent,
Body: BodyComponent,
Footer: FooterComponent
};
export {
card as Card
}
Change your components to render their children
import React, { Component } from 'react'
export default class CardHeader extends Component {
render() {
return (
<div>
{this.props.children}
</div>
)
}
}
Add static properties to Card
import React, { Component } from 'react'
import CardHeader from './CardHeader.jsx'
import CardBody from './CardBody.jsx'
import CardFooter from './CardFooter.jsx'
class Card extends Component {
static Header = CardHeader;
static Body = CardBody;
static Footer = CardFooter;
render() {
return (
{ this.props.children }
)
}
}
export default Card;
Use it like so:
<Card>
<Card.Header>Header</Card/Header>
<Card.Body>Body</Card.Body>
<Card.Footer>Footer</Card.Footer>
</Card>