상세 컨텐츠

본문 제목

Blog App6 StreamDelete

React

by nata_developer 2020. 8. 21. 17:54

본문

0.앱 구조

blog-app

  • api

    • db.json

  • client

    • public

      • index.html

      • modal.html

    • src

      • actions

        • index.js

        • types.js

      • apis

        • streams.js

      • components

        • StreamCreate.js

        • StreamDelete.js

        • StreamEdit.js

        • StreamForm.js

        • StreamList.js

      • App.js

      • GoogleAuth.js

      • Header.js

      • Modal.js

    • reducers

      • authReducer.js

      • index.js

      • streamReducer.js

    • history.js

    • index.js

 

1.public/index.html

  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <div id="modal"></div>
    ...

 

2.public/modal.html

<head>
    <style>
      .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        width: 300px;
        background-color: green;
      }
  
      .content {
        margin-left: 300px;
      }
  
      .modal-body {
        background-color: white;
        margin: auto;
        height: 30%;
        width: 30%;
      }
  
      .modal {
        height: 100%;
        width: 100%;
        position: fixed;
        background-color: grey;
        left: 0;
        top: 0;
        z-index: 10;
      }
  
      .positioned {
        position: relative;
        z-index: 0;
      }
    </style>
  </head>
  <body>
    <div class="modal">
      <div class="modal-body"><h1>I am a modal</h1></div>
    </div>
    <div class="positioned">alskjdflk asldkfjalskdjf asldfkjalskdf</div>
    <div class="sidebar">I am a sidebar</div>
    <div class="content"><h1>I am some content</h1></div>
  </body>

 

3.src/Modal.js

import React from "react";
import ReactDOM from "react-dom";
import history from '../history';

const Modal = props => {
    return ReactDOM.createPortal(
      <div onClick={props.onDismiss} className="ui dimmer modals visible active">
        <div
          onClick={e => e.stopPropagation()}
          className="ui standard modal visible active"
        >
          <div className="header">{props.title}</div>
          <div className="content">{props.content}</div>
          <div className="actions">{props.actions}</div>
        </div>
      </div>,
      document.querySelector('#modal')
    );
  };

export default Modal;

ReactDOM.createPortal

 

Portals 는 리액트 프로젝트에서 컴포넌트를 렌더링하게 될 때,

 

UI 를 어디에 렌더링 시킬지 DOM 을 사전에 선택하여

 

부모 컴포넌트의 바깥에 렌더링 할 수 있게 해주는 기능입니다.

 

이 기능은 리액트 v16 에서 도입된 기능인데요, 기존의 리액트에서 컴포넌트를 렌더링 하게 될 때,

 

children 은 부모컴포넌트의 DOM 내부에 렌더링 되어야 했었습니다

const Wrapper = ({ children }) => {
  return <div>{children}</div>;
}

 

Portals 를 사용하면 DOM 의 계층구조 시스템에 종속되지 않으면서 컴포넌트를 렌더링 할 수 있습니다.

const MyPortal = ({ children }) => {
  const el = document.getElementById('my-portal');
  return ReactDOM.createPortal(children, el);
}

참고:https://velog.io/@velopert/react-portals

 

리액트 - Portals 를 통한 부모 컴포넌트의 외부 DOM 에 컴포넌트 렌더링하기

Portals 는 리액트 프로젝트에서 컴포넌트를 렌더링하게 될 때, UI 를 어디에 렌더링 시킬지 DOM 을 사전에 선택하여 부모 컴포넌트의 바깥에 렌더링 할 수 있게 해주는 기능입니다.

velog.io

 

4.src/components/StreamDelete.js

import React from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import Modal from "../Modal";
import history from "../../history";
import { fetchStream, deleteStream } from "../../actions";

class StreamDelete extends React.Component {
  componentDidMount() {
    this.props.fetchStream(this.props.match.params.id);
  }

  renderActions() {
    const { id } = this.props.match.params;

    return (
      <React.Fragment>
        <button
          onClick={() => this.props.deleteStream(id)}
          className="ui button negative"
        >
          Delete
        </button>
        <Link to="/" className="ui button">
          Cancel
        </Link>
      </React.Fragment>
    );
  }

  renderContent() {
    if (!this.props.stream) {
      return "Are you sure you want to delete this stream?";
    }

    return `Are you sure you want to delete the stream with title: ${this.props.stream.title}`;
  }

  render() {
    return (
      <div>
        StreamDelete
        <Modal
          title="Delete Stream"
          content={this.renderContent()}
          actions={this.renderActions()}
          onDismiss={() => history.push("/")}
        />
      </div>
    );
  }
}
const mapStateToProps = (state, ownProps) => {
  return { stream: state.streams[ownProps.match.params.id] };
};

export default connect(mapStateToProps, { fetchStream, deleteStream })(
  StreamDelete
);

Fragment

 

React의 패턴은 Component가 여러 요소를 반환하는 것이 일반적입니다. 

 

Fragements 를 사용하면 DOM 노드에 추가하지 않고 하위의 목록을 그룹화 할 수 있습니다.

 

 참고:https://a-tothe-z.tistory.com/26

 

[JS] React.js Fragment 알아보기

Fragments React의 패턴은 Component가 여러 요소를 반환하는 것이 일반적입니다. Fragements 를 사용하면 DOM 노드에 추가하지 않고 하위의 목록을 그룹화 할 수 있습니다. render() { return ( ); } 새롭게 짧..

a-tothe-z.tistory.com

 

'React' 카테고리의 다른 글

BlogApp7 StreamShow  (0) 2020.08.21
Blog App3 StreamList  (0) 2020.08.20
React Router를 이용하여 component간에 props 넘겨주기  (0) 2020.08.20
Blog App5 StreamEdit  (0) 2020.08.20
redux-form  (0) 2020.08.20

관련글 더보기