본문 바로가기

Web 개발/react

[react] props와 게시글 작성 및 삭제(3주차)

728x90

모달창안에 첫 째 글제목을 넣어보자

function Modal(){
  return(
    <div className= 'modal'>
        <h4>글제목[0]</h4>
        <p>날짜</p>
        <p>상세내용</p>
    </div>
  )
}

에러가 발생한다 이유는?

function 함수(){
	let a = 10;
}

모든 변수는 함수탈출 불가능

 

글제목이 function app안에 만들어서 그럼

 

>> props문법을 쓰면됨

 

사이트구조는

app은 부모컴포넌트 modal을 자식컴포넌트라고 한다.

 

부모컴포넌트에서 자식컴포넌트로는 state를 전송이 가능하다.

전송할 때 필요한 문법이 props이다.

 

props 문법 사용하는 법

(부모 => 자식 state 전송하는법)

 

1. <자식컴포넌트 작명={state이름}>

2. props 파라미터 등록후 props.작명 사용

   {
        modal == true ? <Modal 글제목={글제목}/> : null
   } 
   
   
  function Modal(props){
  	return(
        <div className= 'modal'>
            <h4>props.글제목</h4>
            <p>날짜</p>
            <p>상세내용</p>
        </div>
  )
}

props 전송은 부모 => 자식만 가능

 

  {
        modal == true ? <Modal color='lightgreen' 글제목={글제목}/> : null
  } 
  
 
 <div className= 'modal' style={{background : props.color}}>
        <h4>{props.글제목[0]}</h4>
        <p>날짜</p>
        <p>상세내용</p>
    </div>

이런식으로 비슷한 컴포넌트를 만들 필요없이 모달에 스타일을 추가 할 수도 있다.

 

모달에 수정버튼을 누르면 제목 바뀌게 하기

 {
        modal == true ? <Modal 글제목변경={글제목변경}  color='lightgreen' 글제목={글제목}/> : null
      } 

function Modal(props){
  return(
    <div className= 'modal' style={{background : props.color}}>
        <h4>{props.글제목[0]}</h4>
        <p>날짜</p>
        <p>상세내용</p>
        <button onClick={ ()=> {
        let copy = [...props.글제목] ; 
        copy[0] = '여자코트 추천'; 
        props.글제목변경(copy);
      }}>수정하기</button>
    </div>
  )
}

 

글 누르면 누른 글의 제목이 모달창안에 뜨게 하기

0번 글을 누르면 0번 글 제목

1번 글을 누르면 1번 글 제목

 

동적인 ui를 만드는법

1. html css로 디자인하기

2. 현재 UI의 상태를 state로 만들기

3. state 종류에 따라 UI가 어떻게 보일지 작성

 

let [title, setTitle] = useState(0);

<h4 onClick={ ()=>{ 
          modal == true ? setModal(false) :
         setModal(true); setTitle(i) }}>{ 글제목[i] } 
         
function Modal(props){
  return(
    <div className= 'modal' style={{background : props.color}}>
        <p>{ props.글제목[props.title] }</p>
        }

i가 바뀌면서 글제목도 바뀌게 됨

 

 

 

새로운 글 발행하기

hrml에선s  <input>을 해야하지만 리액트에서는 닫아줘야함 또는 <input />

 

input 형식

type = 'text' 

type ='range'

type ='checkbox'

<select><select/>

<textarea><textarea/>

 

<input>에 뭔가 입력시 코드실행하고 싶으면

onChange / oninput

<input onChange={()=>{ ??? }} />

onChange는 타이핑 할 때마다 변화를 줌

 

onMouseOver

onScroll

이벤트핸들러들 등등을 찾아서 쓰면 됨

 

<input>에 입력한 값 가져오는법

지금 발생하는 이벤트에 관련한 여러 기능이 담겨있음

 

왜 span (좋아요)태그를 눌러도 모달창이 뜰까?

클릭이벤트는 상위html로 퍼지기 때문에 >> 이벤트버블링

 

<span onClick={(e)=>{ e.stopPropagation() 좋아요변경(좋아요 +1) }}

이벤트버블링을 막을려면  e.stopPropagation() 해주면 됨

 
let [입력값, 입력값변경] = useState('');
<input onChange={(e)=>{ 입력값변경(e.target.value); console.log(입력값)}} />

이러면 input에 입력될때마다 state에 저장이된다.

근데 왜 한글자만 입력할 때는 출력이 안될까

> state 변경함수는 늦게 처리된다.(비동기처리)

 

글 작성하기

<button onClick={ ()=> {
      let copy = [...글제목];
      copy.unshift(입력값);
      글제목변경(copy);
      let copy1 = [...좋아요];
      copy1.push(0);
      좋아요변경(copy1);
      }}>글 작성</button>

array에 추가하는 법은 push,unshift 등 있는데 push는 array의 마지막, unshift는 array의 처음

 

글 삭제하기

글제목.map(function(a,i){
          return (
            <div className='list'>
        <h4 onClick={ ()=>{ 
          modal == true ? setModal(false) :
         setModal(true); setTitle(i) }}>{ 글제목[i] }
        <button onClick={ ()=> {
        let copy = [...글제목];
        copy.splice(i,1);
        글제목변경(copy)
        }}>삭제</button>

현재 날짜 추가하기

import dayjs from "dayjs";

function App() {
  let setTime = () => {
    let dj = dayjs();
    return dj.format("YY-MM-DD (HH:mm)");
  };
}

 <button
              onClick={() => {
                let copy1 = [...date];
                copy1.splice(i, 1);
                setDate(copy1);
              }}
            >
              삭제
</button>

<button
        disabled={!입력값}          #입력하지 않았을 때 글 발행 안되게 하기
        onClick={() => {         
          let copy2 = [...date];
          copy2.unshift(setTime());
          setDate(copy2);
        }}
      >
        글 작성
      </button>

https://jsikim1.tistory.com/196

https://day.js.org/docs/en/display/format

 

 

 

728x90