일기장 만들기

minho·2022년 2월 14일
0

기본 ui준비

DiartEditor컴포넌트

const DiaryEditor = () => {    
    return ();     
};

export default DiaryEditor;

App.js

import './App.css';
import DiaryEditor from './DiaryEditor';

function App() {
  return (
    <div>      
      <DiaryEditor/> //DiaryEditor컴포넌트 연결
    </div>
  );
}

export default App;

useState

useState를 이용하여 이름을 변경한다.

import { useState } from 'react';

const DiaryEditor = () => {
    const [author, setAuthor] = useState("name");
  //괄호의 "name"은 초기값이다.

    return ( 
        <div className='DiaryEditor'>
            <h2>오늘의 일기</h2>
            <div>
                <input
                    value={author}
                />                                  
            </div>
        </div>
    );
};

export default DiaryEditor;


위 화면처럼 아무것도 입력하지 않아도 name이 적혀있는 것을 알 수 있다.


onChange

onChange를 이용하면 변경한 author의 값을 실시간으로 반영할 수 있다.

onChange = {(e) => {}}
여기서 e는 event를 뜻한다.
event란 사용자가 어떤 행동을 하는것을 의미한다.
여기서는 사용자가 input에 값을 입력을하면 event로 간주한다.

import { useState } from 'react';

const DiaryEditor = () => {
    const [author, setAuthor] = useState("name");
  //괄호의 ""는 초기값이다.

    return ( 
        <div className='DiaryEditor'>
            <h2>오늘의 일기</h2>
            <div>
                <input
                    value={author}
                    onChange = { (e) => {
                        console.log(e); 
                        } 
                    }
                />                                  
            </div>
        </div>
    );
};

export default DiaryEditor;

사용자가 input에 값을 입력하면 onChange는 input에 들어오는 값(e)을 가져와 콜백함수로 넘겨준다.

input에 입력할 때마다 console에 무언가 찍히는것을 알 수 있다.

찍힌 객체를 살펴보면 target의 value를 살펴보면 현재 input의 value값을 알 수 있다.
왜 값을 입력해도 value의 값은 바뀌지 않을 까?

현재 value는 author로 설정되어 있는데 author를 변경하려면 useState를 이용해 setAuthor로 변경해야 하기 때문이다.
여기서 setAuthor는 메소드가 아니라 임의로 정해준 이름이다.

(useState의 사용방법을 숙지해야 이해할 수 있다.)

setAuthor로 e.value.target변경

import { useState } from 'react';

const DiaryEditor = () => {
    const [author, setAuthor] = useState("name");
  //괄호의 ""는 초기값이다.

    return ( 
        <div className='DiaryEditor'>
            <h2>오늘의 일기</h2>
            <div>
                <input
                    value={author}
                    onChange = { (e) => {
                        setAuthor (e.target.value);
                        console.log(e.target.value);
                        } 
                    }
                />                                  
            </div>
        </div>
    );
};

export default DiaryEditor;


이제 e.target.value의 값이 input에 입력한데로 바뀌는 것을 볼 수 있다.

이것과 같은 방법으로 여러줄을 입력할 수 있다.

textarea

textarea를 이용하여 여러줄을 입력받을 수 있다.
사용방법은 input과정과 동일하다.

import { useState } from 'react';

const DiaryEditor = () => {
    const [author, setAuthor] = useState("");
    const [content, setContent] = useState("")
  //괄호의 ""는 초기값이다.

    return ( 
        <div className='DiaryEditor'>
            <h2>오늘의 일기</h2>
            <div>
                <input
                    value={author}
                    onChange = { (e) => {
                        setAuthor (e.target.value);
                        console.log(e.target.value);
                        } 
                    }
                />                                  
            </div>
            <div>
                <textarea //<- textarea를 통해 여러줄 입력받기
                    value={content}
                    onChange = {(e)=> {
                        setContent(e.target.value);
                        console.log(e.target.value);
                        }
                    }
                />
            </div>
        </div>
    );
};

export default DiaryEditor;
  • useState를 이용해 content와 setContent를 설정한다.
  • onChange를 이용해 e를 받고 콜백함수를 통해 setContent를 사용하여 value값을 변경한다.

useState 통합

위의 input과 useState는 내용이 비슷하다.
그러므로 하나로 합칠 수 있다.

const DiaryEditor = () => {
    const [author, setAuthor] = useState("");
    const [content, setContent] = useState("")   

이부분을 아래와 같이 바꾼다.

const DiaryEditor = () => {
    const [state, setState] = useState({
        author: "",
        content: "",
    });

author와 content는 이제 setState에 의해 값이 변경되므로 setAuthor와 setContent부분도 변경해준다.

<input
       value={state.author}
       onChange = { (e) => {
           setState({
               author: e.target.value,
               content: state.content,                            
           });                                                 
       }}                    
   />                          
<textarea
        value={state.content}
        onChange = { (e) => {
            setState({
                content: e.target.value,
                author: state.author,
            });                        
        }}                    
    />

주의
input에서는 author만 바꾸고 textarea에서는 content만 바꾸면 되는거 아닌가?

현재 useState의 state는 객체이다.
setState를 이용하여 요소의 값을 바꿀때 다른 값을 지정해주지 않으면 error가 난다.

input에는 author를 바꾸므로 author의 값을 바꿔준다.
그리고 content의 값은 그대로 놔두어야 하므로 본래의 값인 state.content의 값을 넣어준다.

지금은 useState객체 안에 요소가 2개밖에 없지만 많다면 어떻게 해야 할까?

스프레드 연산자를 사용한다.

<input
        value={state.author}
        onChange = { (e) => {
            setState({
              	...state,
                author: e.target.value,                                          
            });                                                 
        }}                    
    />                          

이렇게 하면 state안의 모든 값을 불러올 수 있다.
주의 ...state가 author: e.target.value보다 위에 와야한다.
왜냐하면 ...state가 밑에오면 author의 바꾼 값을 다시 초기화 시키기 때문이다.

마찬가지로 textarea도 ...state를 붙여준다.

<textarea
        value={state.content}
        onChange = { (e) => {
            setState({
                ...state,
                content: e.target.value,                            
            });                        
        }}                    
    />

onChange통합

input과 textarea의 onChange부문을 보면 author, content 부분 말고는 모두 동일하다.

그러므로 이렇게 만들 수 있다.

const [state, setState] = useState({
        author: "",
        content: "",
    });
const handleChangeState = (e) => {
        setState({
            ...state,
            [e.target.name]: e.target.value,                                                     
        });          
    }
<input
        name='author' //<- 추가
        value={state.author}
        onChange = { handleChangeState }                    
    />             
<textarea
        name='content' //<- 추가
        value={state.content}
        onChange = { (e) => {
            setState({
                ...state,
                content: e.target.value,                            
            });                        
        }}                    
    />
  • input, textarea에 name을 추가한다.
    name은 각각 state의 객체와 동일하게 한다.
    state.author, state.content의 변경이 목적이므로
  • handleChangeState의 [e.target.name]에 들어오는 값들은 input의 name인 author, textarea의 name인 content가 된다.

감정지수 만들기



위와같이 select를 이용해 감정지수를 만들어 보자

const DiaryEditor = () => {
    const [state, setState] = useState({
        author: "",
        content: "",
        emotion: 1,
    });
<select
    name='emotion'
    value={state.emotion}
    onChange = {handleChangeState}
>
    <option value={1}>1</option>
    <option value={2}>2</option>
    <option value={3}>3</option>
    <option value={4}>4</option>
    <option value={5}>5</option>                    
</select>

select를 이용해서 숫자나 문자를 선택할 수 있는 박스를 만들 수 있다.

  1. DiaryEditor의 state인자에 emotion을 넣어준다.
    초기값은 1로 설정한다.
  2. input, textarea와 같이 selct에도 state인자와 똑같이 name을 만들어주고, onChange에 handleChangeState를 넣어준다.

저장버튼 만들기

state의 정보를 보내기 위해 저장버튼을 만든다.


각 칸에 정보를 입력한 뒤 일기 저장버튼을 누루면 저장성공이라는 알림과 함게 state를 console에 출력한다.

const handleSubmit = () => {
    console.log(state);
    alert("저장 성공");
}
<button onClick={ handleSubmit }> 일기 저장 </button>
  1. handleSubmit함수를 만든다.
    • state의 상태를 console에 출력
    • alert를 이용해 알람
  2. button을 만든다.
    • onClick을 이용해 클릭하면 handleSubmit()를 실행.
profile
Live the way you think

0개의 댓글