자바스크립트 댓글 기능 구현(feat.토큰)

susu.J·2020년 6월 20일
0
post-thumbnail

login.js

import React from 'react'
import './Login.css' //css파일 가져옴
import LogoText from '../../Image/logo_text.png'
import { withRouter } from 'react-router-dom'

export class Login extends React.Component {
  // state >> 컴포넌트 내부에서 정의하는 상태
  constructor() {
    super()
    this.state = {
      InputId: '',
      InputPw: '',
      ChangeId: '',
      ChangePw: '',
    }
  }
  //어려운버전
  //handleIdInput = (e) => {
  //	console.log(e.target.name, ':', e.target.value);
  //	console.log('e.target.value >>> ', e.target.value);
  //	this.setState({ [e.target.name]: e.target.value });//name은 InputId
  //	this.setState({ ChangeId: e.target.value.includes('@') });
  //};

  //changeHandlePwInput = (e) => {
  //	console.log(e.target.name, ' : ', e.target.value); //name은 InputPw
  //	this.setState({ [e.target.name]: e.target.value }); //객체형태로
  //	this.setState({ ChangePw: e.target.value.length >= 5 ? true : false });
  //};

  //쉬운버전
  handleIdInput = (e) => {
    this.setState({
      InputId: e.target.value,
    })
    this.setState({ ChangeId: e.target.value.includes('@') })
  }
  changeHandlePwInput = (e) => {
    this.setState({
      InputPw: e.target.value,
    })
    this.setState({ ChangePw: e.target.value.length >= 4 ? true : false })
  }

  //!!!ROUTER경로!!!!!
  goToSignup() {
    //if... 조건걸어주기 if (inputId.value.length > )
    this.props.history.push('/main') //main경로
  }

  onClickhandler = (e) => {
    e.preventDefault()
    console.log(this.state)

    fetch(
      'http://10.58.6.117:8001/users/log-in',
{

        method: 'POST', //값이포스트 무조건 string형태로 !  ,
        headers: { Authorization: localStorage.getItem('access_token') },
        body: JSON.stringify({
          //json 스트링화시키겠다 라는 뜻  요 안에 인자로(json화된 자바스크립트 데이터)
          //user_id: this.state.InputId, //성공하면 토큰이 제이슨바디에들어온다
          password: this.state.InputPw,
          username: this.state.InputId,
        }),
      },
    )
      .then((res) => res.json()) //여기에 만약 콘솔만찍으면 콘솔찍어주고 하는일이없다.
      //.then((res) => console.log(res))
      .then((res) => localStorage.setItem('access_token', res.token))
    /* if (res.token) {
      localStorage.setItem('access_token', res.token)*/
    this.props.history.push('/main')
  }
  //res인지 res.지정명칭 있는지 백엔드랑 맞춰서해야된다.

  render() {
    //	console.log('this.state.InputId>>>', this.state.InputId);
    return (
      <div className="Login">
        <section>
          <div className="container">
            <form className="form">
              <div className="logobox">
                <div className="logo">
                  <img src={LogoText} alt="logo" />
                </div>
              </div>
              <div className="form-control">
                <label htmlFor="id" />
                <input
                  onChange={this.handleIdInput} //onchane지정 핸들아이디 인풋을 위 상태로 ,,*/
                  name="InputId" //name지정
                  type="id"
                  placeholder="전화번호, 사용자 이름 또는 이메일"
                />
              </div>
              <div className="form-control">
                <label htmlFor="password" />
                <input
                  name="InputPw" //name지정
                  onChange={this.changeHandlePwInput}
                  type="password"
                  id="WestaPassword"
                  placeholder="비밀번호"
                />
              </div>

              <button
                style={{
                  backgroundColor:
                    this.state.ChangeId && this.state.ChangePw
                      ? '#1989fa'
                      : 'rgba(var(--d69, 0, 149, 246), .3)',
                }}
                type="submit"
                id="submit"
                className="log-in"
                className="btn signup-btn"
                onClick={this.onClickhandler}
              >
                로그인
              </button>
              <p className="forgotpassword"> 비밀번호를 잊으셨나요?</p>
            </form>
          </div>
        </section>
        <section>
          <footer className="footer">
            <div className="copyright">
              <p> &copy; 2020 INSTAGRAM FROM FACEBOOK </p>
            </div>
          </footer>
        </section>
      </div>
    )
  }
}

export default withRouter(Login)

.
.

main.js

import React, { Component, useState } from 'react'
import './Main.css' //css파일 가져옴
import p1 from '../../Image/1.png'
import p2 from '../../Image/2.png'
import p3 from '../../Image/3.png'
import p4 from '../../Image/4.png'
import p6 from '../../Image/6.png'
import p7 from '../../Image/7.png'
import instalogo from '../../Image/instalogo.png'
import main1 from '../../Image/main1.png'
import more from '../../Image/more.png'
import rightoption from '../../Image/rightoption.png'
import leftoption from '../../Image/leftoption.png'
//import Comments from './Comments.jsx';

export class Main extends React.Component {
  constructor() {
    super()

    this.state = {
      item: '',
      items: [], //items라는 빈 배열을 주고, 나중에 map함수 써서 배열을
      //하나하나 돌면서 입력해준 조건이 적용된 배열을 출력하는 함수로 해결
    }

    //  this.changeInputComments = this.changeInputComments.bind(this) //this.method.bid(this)  바인드는 밑에 arrow를 써주면 필요없다
    //  this.submitItem = this.submitItem.bind(this)
  }
  //this.onChange={this.changeInputComments를 pass하고 있으므로 binding이 필요하다.}

  changeInputComments = (event) => {
    let name = event.target.name
    let value = event.target.value

    this.setState({ [name]: value })
  }

  submitItem = (e) => {
    e.preventDefault()
    console.log(this.state)

    let items = this.state.items
    let item = this.state.item

    items.push(item)
    this.setState({ item: '' }) 
    //item이 댓글달기쪽이니까 items에 item을 넣어주고 item은 빈값이되게 해준다.
    //여기서 작성한 item들을 items배열에 넣어주게 되는데, 게시버튼을 클릭함과 동시에 빈 배열인 items에
    //push함수를 통해 추가하고 setState를 통해 배열을 새로운 items 로 업뎃한다.

    fetch('http://10.58.6.117:8001/comments', {
      method: 'POST',
      headers: { Authorization: localStorage.getItem('access_token') }, //객체형태로 만들고 그안에 au....씀
      //authorization에 그 유저들의 정보를 담음 (완전민감한정보 ) 이런 완전 중요한 것들을 따로 담아서 보내줄때 레더스를 쓴다.
      body: JSON.stringify({
        comment: this.state.item,
      }),
    })
      
      //.then((res) => res.json())
      //.then((res) => console.log(res.status)) //200인지 400 500인지 확인할수있다.
      //위 .then 브라우저에저장한다.완전최상위! 항상거기들러서 가져올수있게
      .then((res) => console.log(res))

  }

  render() {
    return (
      <>
        <header>
          <div className="nav">
            <div className="middle_nav">
              <div className="logo">
                <img src={instalogo} alt="logo" />
              </div>
              <div className="search">
                <div className="search-text">
                  <input
                    className="search-box"
                    type="text"
                    placeholder="                        검색"
                  />
                  <div className="search-text-in">
                    <i class="fas fa-search"></i>
                    <div class="search-img"></div>
                    <span className="research"></span>
                  </div>
                </div>
              </div>
              <div className="rightoptions">
                <div className="headerpic">
                  <div className="home">
                    <a href="/">
                      <svg
                        aria-label=""
                        className="_8-yf5 "
                        fill="#262626"
                        height="22"
                        viewBox="0 0 48 48"
                        width="22"
                      >
                        <path d="M45.5 48H30.1c-.8 0-1.5-.7-1.5-1.5V34.2c0-2.6-2.1-4.6-4.6-4.6s-4.6 2.1-4.6 4.6v12.3c0 .8-.7 1.5-1.5 1.5H2.5c-.8 0-1.5-.7-1.5-1.5V23c0-.4.2-.8.4-1.1L22.9.4c.6-.6 1.6-.6 2.1 0l21.5 21.5c.3.3.4.7.4 1.1v23.5c.1.8-.6 1.5-1.4 1.5z"></path>
                      </svg>
                    </a>
                  </div>
                </div>
                <div className="headerpic">
                  <div className="direct">
                    <a href="/direct/inbox/">
                      <svg
                        aria-label="Direct"
                        className="_8-yf5 "
                        fill="#262626"
                        height="22"
                        viewBox="0 0 48 48"
                        width="22"
                      >
                        <path d="M47.8 3.8c-.3-.5-.8-.8-1.3-.8h-45C.9 3.1.3 3.5.1 4S0 5.2.4 5.7l15.9 15.6 5.5 22.6c.1.6.6 1 1.2 1.1h.2c.5 0 1-.3 1.3-.7l23.2-39c.4-.4.4-1 .1-1.5zM5.2 6.1h35.5L18 18.7 5.2 6.1zm18.7 33.6l-4.4-18.4L42.4 8.6 23.9 39.7z"></path>
                      </svg>
                    </a>
                  </div>
                </div>
                <div className="headerpic">
                  <div className="explore">
                    <a href="/explore/">
                      <svg
                        aria-label="사람 찾기"
                        className="_8-yf5 "
                        fill="#262626"
                        height="22"
                        viewBox="0 0 48 48"
                        width="22"
                      >
                        <path
                          clipRule="evenodd"
                          d="M24 0C10.8 0 0 10.8 0 24s10.8 24 24 24 24-10.8 24-24S37.2 0 24 0zm0 45C12.4 45 3 35.6 3 24S12.4 3 24 3s21 9.4 21 21-9.4 21-21 21zm10.2-33.2l-14.8 7c-.3.1-.6.4-.7.7l-7 14.8c-.3.6-.2 1.3.3 1.7.3.3.7.4 1.1.4.2 0 .4 0 .6-.1l14.8-7c.3-.1.6-.4.7-.7l7-14.8c.3-.6.2-1.3-.3-1.7-.4-.5-1.1-.6-1.7-.3zm-7.4 15l-5.5-5.5 10.5-5-5 10.5z"
                          fillRule="evenodd"
                        ></path>
                      </svg>
                    </a>
                  </div>
                </div>
                <div className="headerpic">
                  <div className="heart">
                    <a href="/accounts/activity/">
                      <svg
                        aria-label="활동 피드"
                        className="_8-yf5 "
                        fill="#262626"
                        height="22"
                        viewBox="0 0 48 48"
                        width="22"
                      >
                        <path d="M34.6 6.1c5.7 0 10.4 5.2 10.4 11.5 0 6.8-5.9 11-11.5 16S25 41.3 24 41.9c-1.1-.7-4.7-4-9.5-8.3-5.7-5-11.5-9.2-11.5-16C3 11.3 7.7 6.1 13.4 6.1c4.2 0 6.5 2 8.1 4.3 1.9 2.6 2.2 3.9 2.5 3.9.3 0 .6-1.3 2.5-3.9 1.6-2.3 3.9-4.3 8.1-4.3m0-3c-4.5 0-7.9 1.8-10.6 5.6-2.7-3.7-6.1-5.5-10.6-5.5C6 3.1 0 9.6 0 17.6c0 7.3 5.4 12 10.6 16.5.6.5 1.3 1.1 1.9 1.7l2.3 2c4.4 3.9 6.6 5.9 7.6 6.5.5.3 1.1.5 1.6.5.6 0 1.1-.2 1.6-.5 1-.6 2.8-2.2 7.8-6.8l2-1.8c.7-.6 1.3-1.2 2-1.7C42.7 29.6 48 25 48 17.6c0-8-6-14.5-13.4-14.5z"></path>
                      </svg>
                    </a>
                  </div>
                </div>
                <div className="profilepic-right">
                  <img src={p6} />
                </div>
              </div>
            </div>
          </div>
        </header>
        <body>
          <main class="container1">
            <div className="totalbox">
              <div className="sidebar">
                <div className="sidebar-header">
                  <div className="sideprofile-img">
                    <img src={p6} />
                  </div>
                  <div className="sideprofile-info">
                    <div className="name">
                      <p>spring1</p>
                    </div>
                    <div className="nickname">
                      <p>pikapika</p>
                    </div>
                  </div>
                </div>
                <div className="listmenu">
                  <div className="listmenu-text">
                    <div className="text1">회원님을 위한 추천</div>
                    <a href="#" className="text2">
                      모두보기
                    </a>
                  </div>
                  <div className="recommend-profiles">
                    <div className="recommend-left">
                      <div className="recommend-img">
                        <img src={p1} />
                      </div>
                      <div className="recommend-txt">
                        <div className="user-id">
                          <p>onny_hy</p>
                        </div>
                        <div className="user-fallow">
                          회원님을 팔로우합니다.
                        </div>
                      </div>
                    </div>
                    <button type="btn" className="btn">
                      팔로우
                    </button>
                  </div>
                  <div className="recommend-profiles">
                    <div className="recommend-left">
                      <div className="recommend-img">
                        <img src={p7} />
                      </div>
                      <div className="recommend-txt">
                        <div className="user-id">
                          <p>Baker_lee</p>
                        </div>
                        <div className="user-fallow">
                          회원님을 팔로우합니다.
                        </div>
                      </div>
                    </div>
                    <button type="btn" className="btn">
                      팔로우
                    </button>
                  </div>
                  <div className="recommend-profiles">
                    <div className="recommend-left">
                      <div className="recommend-img">
                        <img src={p3} />
                      </div>
                      <div className="recommend-txt">
                        <div className="user-id">
                          <p>js_k</p>
                        </div>
                        <div className="user-fallow">
                          회원님을 팔로우합니다.
                        </div>
                      </div>
                    </div>
                    <button type="btn" className="btn">
                      팔로우
                    </button>
                  </div>
                  <div className="recommend-profiles">
                    <div className="recommend-left">
                      <div className="recommend-img">
                        <img src={p4} />
                      </div>
                      <div className="recommend-txt">
                        <div className="user-id">
                          <p>hyj1020</p>
                        </div>
                        <div className="user-fallow">
                          회원님을 팔로우합니다.
                        </div>
                      </div>
                    </div>
                    <button type="btn" className="btn">
                      팔로우
                    </button>
                  </div>
                  <div className="recommend-profiles">
                    <div className="recommend-left">
                      <div className="recommend-img">
                        <img src={p2} />
                      </div>
                      <div className="recommend-txt">
                        <div className="user-id">
                          <p>paran12</p>
                        </div>
                        <div className="user-fallow">
                          회원님을 팔로우합니다.
                        </div>
                      </div>
                    </div>
                    <button type="btn" className="btn">
                      팔로우
                    </button>
                  </div>
                </div>

                <div className="side-under-container">
                  <div className="footer-nav">
                    <ul>
                      <li>
                        <p>소개 </p>
                      </li>
                      <li>
                        <p>도움말 </p>
                      </li>
                      <li>
                        <p>홍보 센터 </p>
                      </li>
                      <li>
                        <p>API </p>
                      </li>
                      <li>
                        <p>채용 정보 </p>
                      </li>
                      <li>
                        <p>개인정보처리방침 </p>
                      </li>
                      <li>
                        <p>약관 </p>
                      </li>
                      <li>
                        <p>위치 </p>
                      </li>
                      <li>
                        <p>인기 계정 </p>
                      </li>
                      <li>
                        <p>해시 태그 </p>
                      </li>
                      <li>
                        <p>언어</p>
                      </li>
                    </ul>
                  </div>
                  <div className="copyright">
                    <p> &copy; 2020 INSTAGRAM FROM FACEBOOK </p>
                  </div>
                </div>
              </div>

              <div className="feedcontainer">
                <div className="feed">
                  <div className="feeds_header">
                    <div className="profile-img">
                      <img src={p6} />
                    </div>
                    <div className="profile-info">
                      <div className="name">spring1</div>
                    </div>
                    <div className="more">
                      <img src={more} />
                    </div>
                  </div>
                  <div className="content">
                    <img src={main1} alt="" />
                  </div>
                  <div className="option-box">
                    <div className="leftoptions">
                      <img src={leftoption} />
                      <img src={rightoption} id="img2" />
                    </div>
                  </div>
                  <div className="likelike">
                    <p>kkk0908님여러명이 좋아합니다</p>
                  </div>
                  <div className="description">
                    <p>
                      <span className="username">spring1</span> 우리동네 맛집
                    </p>
                  </div>

                  <div>
                    <div className="comments" name="replies">
                      <p>
                        <span className="username1">chlchoi</span> 좋아요~{' '}
                        <i class="fa fa-heart-0" aria-hidden="true"></i>
                      </p>
                      <p>
                        <span className="username1">jooS_</span> 좋아요~{' '}
                        <i class="fa fa-heart-0" aria-hidden="true"></i>{' '}
                      </p>
                      <div className="datdat" name="datdate">
                        {this.state.items.map((item) => {
                          return (
                            <p>
                              <span className="username1">user1</span> {item}
                            </p>
                          )
                        })}
                      </div>
                      <p>
                        <span className="time">1시간전 </span>
                      </p>
                    </div>
                  </div>

                  <form className="addcomment">
                    <textarea
                      onChange={this.changeInputComments}
                      value={this.state.item}
                      className="Add"
                      id="Add"
                      type="text"
                      placeholder=" 댓글달기..."
                      name="item" //name지정/////////////////////////////////////////////////////////////////////////
                    ></textarea>
                    <button
                      onClick={this.submitItem}
                      className="Submit"
                      id="Submit"
                      type="button"
                    >
                      게시
                    </button>
                  </form>
                </div>
              </div>
            </div>
          </main>
        </body>
      </>
    )
  }
}

export default Main

신기하다 신기해 🌟

profile
on the move 👉🏼 https://sjeong82.tistory.com/

0개의 댓글