0
내 사이트의 작업 세부 정보 표시를 관리하는 다소 큰 React 구성 요소가 있습니다.React 구성 요소의 반복 횟수가 많음
내가
- 스마트 한 구성 요소는 대화 상자를 열기위한 몇 가지 옵션이하고 싶으면 몇 가지가 있습니다. 각 대화 상자마다 별도의 열기 및 닫기 기능이 있습니다. 예를 들어
handleImageGridShow
및handleImageGridClose
입니다. 이 문제를 더욱 간결하게 처리 할 수있는 방법이 있습니까? - 저는 작업에 대한 세부 정보를 보여주는 많은 프레젠테이션 구성 요소 (예 :
ViewJobDetails
)가 있습니다. 내 문제는 내가 각 구성 요소에 소품으로 전달해야하고 동일한 소품을 계속 반복해서 전달해야한다는 것입니다. firebase에서 데이터를로드 할 때 종종 유사한 검사를 수행해야합니다. 구성 요소를 렌더링하기 전에 데이터가 존재하는 경우 (
e.g.this.state.selectedImageGrid && <ImageGridDialog />
). 이것에 관해 더 이상 영리한 방법이 있습니까?가져 오기 import React, {Component} from 'react';
import { withStyles } from 'material-ui/styles'; import ViewJobAttachment from "../../components/jobs/viewJobAttachment"; import ViewJobDetails from "../../components/jobs/viewJob/viewJobDetails"; import ViewJobActions from "../../components/jobs/viewJob/viewJobActions"; import ViewCompanyDetails from "../../components/jobs/viewJob/viewCompanyDetails"; import ViewClientsDetails from "../../components/jobs/viewJob/viewClientsDetails"; import ViewProductsDetails from "../../components/jobs/viewJob/viewProductsDetails"; import ViewAttachmentDetails from "../../components/jobs/viewJob/viewAttachmentDetails"; import ViewEventLogDetails from "../../components/jobs/viewJob/viewEventLogDetails"; import ViewSummaryDetails from "../../components/jobs/viewJob/viewSummary"; import {FirebaseList} from "../../utils/firebase/firebaseList"; import SimpleSnackbar from "../../components/shared/snackbar"; import {calculateTotalPerProduct} from "../../utils/jobsService"; import BasicDialog from "../../components/shared/dialog"; import ImageGrid from "../../components/shared/imageGrid"; import Spinner from "../../components/shared/spinner"; import ViewPinnedImageDialog from "../../components/jobs/viewEntry/viewPinnedImage"; import { Redirect } from 'react-router-dom'; const styles = theme => ({ wrapper: { marginBottom: theme.spacing.unit*2 }, rightElement: { float: 'right' } }); const ImageGridDialog = (props) => { return ( <BasicDialog open={!!props.selectedImageGrid} handleRequestClose={props.handleRequestClose} fullScreen={props.fullScreen} title={props.title} > <ImageGrid selectedUploads={props.selectedImageGrid} handleClickOpen={props.handleClickOpen}/> </BasicDialog> ) }; class ViewJob extends Component { constructor() { super(); this.state = { currentJob: null, entries: [], promiseResolved: false, attachmentDialogOpen: false, openAttachment: null, selectedImageGrid: false, selectedPinnedImage: false, showSnackbar: false, snackbarMsg: '', markedImageLoaded: false, loading: true, redirect: false }; this.firebase = new FirebaseList('jobs'); this.handleJobStatusChange = this.handleJobStatusChange.bind(this); this.handleImageGridShow = this.handleImageGridShow.bind(this); this.handleImageGridClose = this.handleImageGridClose.bind(this); this.handlePinnedImageClose = this.handlePinnedImageClose.bind(this); this.handlePinnedImageShow = this.handlePinnedImageShow.bind(this); this.handleMarkedImageLoaded = this.handleMarkedImageLoaded.bind(this); this.handleRemove = this.handleRemove.bind(this); this.pushLiveToClient = this.pushLiveToClient.bind(this); } componentDidMount() { this.firebase.db().ref(`jobs/${this.props.id}`).on('value', (snap) => { const job = { id: snap.key, ...snap.val() }; this.setState({ currentJob: job, loading: false }) }); const previousEntries = this.state.entries; this.firebase.db().ref(`entries/${this.props.id}`).on('child_added', snap => { previousEntries.push({ id: snap.key, ...snap.val() }); this.setState({ entries: previousEntries }) }); } handleRemove() { this.firebase.remove(this.props.id) .then(() => { this.setState({redirect: true}) }) }; pushLiveToClient() { const updatedJob = { ...this.state.currentJob, 'lastPushedToClient': Date.now() }; this.firebase.update(this.state.currentJob.id, updatedJob) .then(() => this.handleSnackbarShow("Job pushed live to client")) } handleJobStatusChange() { const newState = !this.state.currentJob.completed; const updatedJob = { ...this.state.currentJob, 'completed': newState }; this.firebase.update(this.state.currentJob.id, updatedJob) } handleSnackbarShow = (msg) => { this.setState({ showSnackbar: true, snackbarMsg: msg }); }; handleSnackbarClose= (event, reason) => { if (reason === 'clickaway') { return; } this.setState({ showSnackbar: false }); }; handleAttachmentDialogClose =() => { this.setState({attachmentDialogOpen: false}) }; handleClickOpen = (file) => { this.setState({ attachmentDialogOpen: true, openAttachment: file }); }; handleImageGridShow(imageGrid) { this.setState({selectedImageGrid: imageGrid}) } handleImageGridClose() { this.setState({selectedImageGrid: false}) } handlePinnedImageShow(pinnedImage) { this.setState({selectedPinnedImage: pinnedImage}) } handlePinnedImageClose() { this.setState({selectedPinnedImage: false}) } handleMarkedImageLoaded() { this.setState({markedImageLoaded: true}) } render() { const {classes} = this.props; let {_, costPerItem} = calculateTotalPerProduct(this.state.entries); if (this.state.redirect) { return <Redirect to='/jobs' push/> } else { if (this.state.loading) { return <Spinner/> } else { return ( <div className={styles.wrapper}> {this.state.currentJob && <div> <ViewJobActions currentJob={this.state.currentJob} handleJobStatusChange={this.handleJobStatusChange} pushLiveToClient={this.pushLiveToClient} /> <ViewJobDetails currentJob={this.state.currentJob}/> <ViewCompanyDetails currentJob={this.state.currentJob}/> <ViewClientsDetails currentJob={this.state.currentJob}/> <ViewProductsDetails currentJob={this.state.currentJob}/> {this.state.currentJob.selectedUploads && this.state.currentJob.selectedUploads.length > 0 ? <ViewAttachmentDetails currentJob={this.state.currentJob} handleClickOpen={this.handleClickOpen}/> : null} <ViewEventLogDetails jobId={this.state.currentJob.jobId} jobKey={this.state.currentJob.id} entries={this.state.entries} handlePinnedImageShow={this.handlePinnedImageShow} handleImageGridShow={this.handleImageGridShow}/> <ViewSummaryDetails stats={costPerItem}/> <ViewJobAttachment open={this.state.attachmentDialogOpen} handleRequestClose={this.handleAttachmentDialogClose} attachment={this.state.openAttachment} /> {this.state.selectedImageGrid && <ImageGridDialog selectedImageGrid={this.state.selectedImageGrid} handleRequestClose={this.handleImageGridClose} handleClickOpen={this.handleClickOpen} title="Pictures for job" fullScreen={false}/>} {this.state.selectedPinnedImage && <ViewPinnedImageDialog attachment={this.state.selectedPinnedImage} open={!!this.state.selectedPinnedImage} markedImageLoaded={this.state.markedImageLoaded} handleMarkedImageLoaded={this.handleMarkedImageLoaded} handleRequestClose={this.handlePinnedImageClose} otherMarkedEntries={this.state.entries} /> } <SimpleSnackbar showSnackbar={this.state.showSnackbar} handleSnackbarClose={this.handleSnackbarClose} snackbarMsg={this.state.snackbarMsg}/> </div>} </div> ); } } } } export default withStyles(styles)(ViewJob);