2016-12-21 10 views
0

나는 React에 비교적 새로운데 어디서나 열 수있는 모달을 설정하려고합니다. 다음은 내가 모달을 여는 방법입니다 :앱의 아무 곳에서나 열 수있는 반응 모달을 설정하려면 어떻게해야하나요?

class SearchResults extends React.Component { 
    static propTypes = { 
    status: React.PropTypes.string.isRequired, 
    results: React.PropTypes.array.isRequired, 
    onResultClick: React.PropTypes.func.isRequired 
    } 

    constructor(props) { 
    super(props) 
    } 

    onUploadButtonClick() { 
    console.log('here'); 
    } 

    render() { 
    const uploadButtonFn = this.onUploadButtonClick 
    let childElements = []; 

    childElements.unshift((
     <div className="upload-button-wrapper" key="upload-button"> 
     <button type="button" className="upload-button" onClick={uploadButtonFn}><span>+</span> Upload Your Vidy</button> 
     </div> 
    )) 

    return (
     <div className='search-results'> 
     <div className='inner-content'> 
      {(() => { 
      if (this.props.status === 'fetching') { 
       return <h1>searching</h1> 
      } 

      if (this.props.status === 'ready') { 
       return (
       <Masonry 
        className={'my-gallery-class'} // default '' 
        elementType={'div'} // default 'div' 
        disableImagesLoaded={false} // default false 
        updateOnEachImageLoad={false} // default false and works only if disableImagesLoaded is false 
       > 
        {childElements} 
       </Masonry> 
      ) 
      } 
      })()} 
     </div> 
     <GetMoreResult /> 
     </div> 
    ) 
    } 
} 

export default SearchResults 

이것이 제가 어떻게 모달을 열려고하는지입니다. 나는 거의 긍정적이다. 훨씬 좋은 방법이있다. 나는 redux을 사용하고 있다고 생각합니다. 나는 프로젝트를 물려 받았다. 그래서 나는 그걸 제대로하지 못했을 것이다.

도움을 주시면 감사하겠습니다. 내 기본 레이아웃에 모달을 포함해야한다고 생각하지만 어떻게 트리거합니까?

답변

1

코드가 실제로 어떻게 작동하는지 잘 모르는 경우 connect()은 어디에 있습니까? 어느 곳에서나 당신이 redux를 사용하기를 원한다고 생각합니다.

//action 
const toggleModal = (isVisible) => ({ 
    type: "TOGGLE_MODAL", 
    isVisible: isVisible 
}); 

//reducer 
export default (state={}, action) => { 
    switch (action.type) { 
     case "TOGGLE_MODAL": 
      return {...state, isVisible: action.isVisible} 
     default: 
      return state; 
    } 
} 

//connect() allows us to dispatch an action 
class RandomClassElseWhereInApp extends connect()(React.Component { 
    constructor(props) { 
     super(props) 
    } 
    OpenModal =() => this.props.dispatch(toggleModal(true)) 
    render() { 
     return (
     ); 
    } 
}) 

//Gives us access to the store 
const mapStateToProps = (state) => ({ 
    state.Modal.isVisible 
}); 

//This is a smart component 
class Modal extends connect(mapStateToProps)(React.Component { 
    constructor(props) { 
    super(props) 
    } 
    componentWillReceiveProps(nextProps) { 
    //Empty string for display sets it to original value 
    const display = "" ? this.props.isVisible : "none"; 

    this.setState({myModalStyle: {display: display}}); 
    } 
    render() { 
    return (
     <Popup style={this.state.myModalStyle}/> 
    ); 
    } 
}) 

//This is a dumb component 
const Popup = ({style}) => (
    <div class="popup" style={style} /> 
); 
1

이에 대한 우리의 솔루션은 이런 식입니다 : 당신은 우리가 그것과 관련이없는 것 경우에도 다른 구성 요소에서 모달을 보여줄 수있는 방법을 볼 수 있도록 이것은 단지 예입니다 당신은 REDUX 및 react-를 사용하는 경우 redux.

먼저 모달을 표시할지 여부를 결정하기 위해 일부 동작 생성자와 일부 redux 상태를 만듭니다.

// modal-action-reducer.js 

export const ActionTypes = { 
    CLOSE_MODAL: 'CLOSE_MODAL', 
    OPEN_MODAL: 'OPEN_MODAL' 
}; 

export const ActionCreators = { 
    OpenModal = id => ({ type: ActionTypes.OPEN_MODAL, payload: { id } }), 
    CloseModal:() => ({ type: ActionTypes.CLOSE_MODAL }) 
}; 

// this part of the state will be on something like `state.visibleModal` 
export const reducer = (state = null, action) => { 
    switch (action.type) { 
    case ActionTypes.OPEN_MODAL: 
     return action.payload.id; 

    case ActionTypes.CLOSE_MODAL: 
     return null; 

    default: 
     return state; 
    } 
}; 

다음 실제 모달 UI를 장식하는 상위 구성 요소를 만듭니다.

// ModalDecorator.jsx 

import React from 'react'; 
import {connect} from 'react-redux'; 
import {ActionCreators} from './modal-action-reducer.js'; 

export default function ModalDecorator (modalId) { 
    return function (WrappedModalComponent) { 

    class WrapperComponent extends React.Component { 
     render() { 
     const {isVisible, ...otherProps} = this.props; 
     return isVisible 
      ? <WrappedModalComponent {...otherProps} /> 
      : <div style={{ display: 'none' }} >; 

     } 
    } 

    // get whether this modal is visible by checking the state from the reducer against the modal id 
    const mapStateToProps = state => ({ 
     isVisible: state.visibleModal === modalId 
    }); 

    // for convenience we can add a closeModal prop to all modals 
    const mapDispatchToProps = dispatch => ({ 
     closeModal:() => dispatch(ActionCreators.CloseModal()); 
    }); 

    return connect(mapStateToProps, mapDispatchToProps)(WrapperComponent); 
    } 
} 

그런 다음 실제 모달 :

// ModalDeclarations.jsx 
import MyModal from './MyModal.jsx'; 
import SomeOtherModal from './SomeOtherModaal.jsx'; 

const ModalDeclarations =() => (
    <div> 
    <MyModal/> 
    <SomeOtherModal/> 
    </div> 
); 

export default ModalDeclarations; 

과에서를 여기

// MyModal.jsx 

import React from 'react'; 
import ModalDecorator from './ModalDecorator.jsx'; 

class MyModal extends React.Component { 
    render() { /* Do your thing here */ } 
} 

export default ModalDecorator('my-modal-id')(MyModal); 

한 가지주의해야 할 점은 모든 조동사 어딘가에 렌더링 할, 그래서 그들을 위해 기본 컨테이너를 만드는 것입니다 App.jsx

import React from 'react' 
import ModalDeclarations from './ModalDeclarations.jsx'; 

export default class App extends React.Component { 
    render() { 
    return (
     <div> 
     {/* Other bits of your app here */} 
     <ModalDeclarations /> 
     </div> 
    ); 
    } 
} 

마지막으로 OpenModal 액션 제작자를 사용하여 어디서나 모달을 열 수 있습니다. 이것은 소품에서 modalId를 사용하여 모달을 여는 버튼입니다.

// ModalButton.jsx 

import React from 'react'; 
import {connect} from 'react-redux'; 
import {ActionCreators} from './modal-action-reducer.js'; 

const mapDispatchToProps = (dispatch, ownProps) => ({ 
    openModal:() => dispatch(ActionCreators.OpenModal(ownProps.modalId)) 
}); 

class ModalButton extends React.Component { 
    render() { 
    return (
     <div onClick={this.props.openModal} > 
     {this.props.children} 
     </div> 
    ) 
    } 
} 

export default connect(null, mapDispatchToProps)(ModalButton); 

ModalButton.propTypes = { 
    modalId: React.PropTypes.string.isRequired 
};