我将React与Material UI结合使用。我有一个模式组件和一个ButtonAppBar。在ButtonAppBar内部,有一个我添加的购物车图标。我对React还是有点陌生,想知道单击购物车时显示模态的最佳方法。提前致谢。
这是我的App.js:
import React, { Component } from 'react';
import { BrowserRouter } from 'react-router-dom';
import { Route } from 'react-router-dom';
import './App.css';
import ShopHome from './containers/ShopHome';
import ButtonAppBar from './components/ButtonAppBar';
import SimpleModalWrapped from './containers/ShoppingCartModal';
class App extends Component {
handle
render() {
return (
<BrowserRouter>
<div>
<ButtonAppBar />
<SimpleModalWrapped />
<Route exact path="/" component={ShopHome} />
</div>
</BrowserRouter>
);
}
}
export default App;
这是我的ButtonAppBar:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import SvgIcon from '@material-ui/core/SvgIcon';
import ShoppingCart from '@material-ui/icons/ShoppingCart';
const styles = {
root: {
flexGrow: 1,
},
grow: {
flexGrow: 1,
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
appBar: {
marginBottom: 50,
}
};
function ButtonAppBar(props) {
const { classes } = props;
return (
<div className={classes.root}>
<AppBar style={styles.appBar} position="static">
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" className={classes.grow}>
Velo-Velo
</Typography>
<Button color="inherit">Checkout</Button>
<SvgIcon>
<ShoppingCart />
</SvgIcon>
</Toolbar>
</AppBar>
</div>
);
}
ButtonAppBar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(ButtonAppBar);
这是模态:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import Modal from '@material-ui/core/Modal';
import Button from '@material-ui/core/Button';
function rand() {
return Math.round(Math.random() * 20) - 10;
}
function getModalStyle() {
const top = 50 + rand();
const left = 50 + rand();
return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`,
};
}
const styles = theme => ({
paper: {
position: 'absolute',
width: theme.spacing.unit * 50,
backgroundColor: theme.palette.background.paper,
boxShadow: theme.shadows[5],
padding: theme.spacing.unit * 4,
},
});
class SimpleModal extends React.Component {
state = {
open: false,
};
handleOpen = () => {
console.log('clicked')
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
render() {
const { classes } = this.props;
return (
<div>
{/* <Typography gutterBottom>Click to get the full Modal experience!</Typography>
<Button onClick={this.handleOpen}>Open Modal</Button> */}
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
open={this.state.open}
onClose={this.handleClose}
>
<div style={getModalStyle()} className={classes.paper}>
<Typography variant="h6" id="modal-title">
Text in a modal
</Typography>
<Typography variant="subtitle1" id="simple-modal-description">
Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
</Typography>
<SimpleModalWrapped />
</div>
</Modal>
</div>
);
}
}
SimpleModal.propTypes = {
classes: PropTypes.object.isRequired,
};
// We need an intermediary variable for handling the recursive nesting.
const SimpleModalWrapped = withStyles(styles)(SimpleModal);
export default SimpleModalWrapped;
答案 0 :(得分:0)
您最好的选择是使用Redux之类的东西。作为惰性策略,有一个包含两个组件的高阶组件。高阶组件可以具有单击该图标时需要运行的功能,并且它会更改高阶组件的状态。
说你有
import React, { Component } from 'react'
import ComponentWithIcon from './icon-holder'
import ModalComponent from './modal'
class OuterContainer extends Component {
state = { modalOpen: false }
setModal = openOrClose => this.setState({modalOpen: openOrClose})
render(){
const {setModal, state: { modalOpen } } = this
return (
<>
<ComponentWithIcon
handleModalClick={setModal}
/>
<ModalComponent
isOpen={modalOpen}
handleModalClick={setModal}
/>
</>
)
}
}
结果不是由Modal组件确定它是否处于打开状态(处于自己的状态),这意味着只有它知道OuterContainer
将确定它当前是否处于打开状态。 。OuterContainer也是handleTheClickEvent
的点击对象,因此图标将运行OuterComponent
的功能到setState ...
此功能(clickHandler)和状态通过其子项传递给每个子组件。由于模态需要能够关闭,因此也可以从OuterComponent传入它,并且可以使用相同的state.modalOpen
和可能是相同的传递动作(clickHandler)进行切换(或者如果您需要出于某种原因,您可以通过OuterComponent定义一个openModal
/ closeModal
并传递两个要由模式运行的回调。
使用redux(带有react-redux),您将拥有一个<Provider>
组件,它是其所有子组件的较高阶组件。提供者保持通过redux的createStore()
生成的常规存储的状态,然后该存储获得操作操作中央存储的操作,并且由于它处于顶层,因此它能够注入其当前状态(或其中的特定部分) )到提供程序中包含的任何组件(每个组件)。这些组件中的每一个都能够使用dispatch()
将消息发送到该提供程序,然后将这些操作分派给商店,从而导致商店被内部具有更新内容的新商店替换(例如,模式开了)。
import React from 'react'
const MyModal = ({isOpen, handleModal }) => (
<div className={`modal ${isOpen ? 'is-showing' : 'is-hidden'}`}>
<div
className='toolbar'
>
<CloseButton onClick={() => handleModal(false)} />
</div>
<div>
{/* Modal content */}
</div>
</>
)