Reactでマテリアル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;
あなたの最善の策は、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}
/>
</>
)
}
}
結果として、モーダルコンポーネントが開いているかどうかを判断するのではなく(独自の状態になっている)、つまり、現在開いているかどうかを知るのは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>
</>
)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加