profile image

L o a d i n g . . .

 

랜더링?

화면에 표시한다

 

 

DiaryList 컴포넌트 생성

일기 리스트를 담을 DiaryList.js 컴포넌트를 생성해준다

const DiaryList = () => {
 return (<div className="DiaryList">
    <h2>일기 리스트</h2>
 </div>
 );
};

export default DiaryList;

 

 

생성된 컴포넌트를 App 컴포넌트 에서도 불러온다

import DiaryList from './DiaryList';
function App() {
  return (
    <div className="App">
      <DiaryEditor></DiaryEditor>
      <DiaryList></DiaryList>
    </div>

  );
}

앱 컴포넌트의 자식으로 배치해줬다.

 

 

이제 다이어리에디터 컴포넌트 밑에 다이어리리스트 컴포넌트를 볼 수 있다.

 

이제 이 리스트에 저장한 일기들을  리스트 형태로 출력시키는게 목표

 

 

 

 


하지만 처음에 다 만들면 조금 어려울 수 있으니

임시배열을 만들어서 DiaryList에 prop 으로 리스트 전달 연습먼저

 

 

 

//일기 리스트 역할을 할 dummyList 배열 생성
const dummyList = [
  {
    id: 1,
    author: "이나당",
    content: "첫일기",
    emotion: 4,
    create_date: new Date().getTime()
  }
]

앱 컴포넌트에 dummyList 배열객체를 생성해주었다.

추가로 작성날짜를 넣어주었다.

 

 

const dummyList = [
  {
    id: 1,
    author: "이나당",
    content: "첫일기",
    emotion: 4,
    create_date: new Date().getTime()
  },
  {
    id: 2,
    author: "길동당",
    content: "둘일기",
    emotion: 3,
    create_date: new Date().getTime()
  },
  {
    id: 3,
    author: "곰당",
    content: "삼일기",
    emotion: 2,
    create_date: new Date().getTime()
  },
  {
    id: 4,
    author: "지당",
    content: "넷일기",
    emotion: 1,
    create_date: new Date().getTime()
  }
]

더미데이터니까 하나 말고 배열에 여러 값을 넣어주었다.

 

 

이제 만들어진 DummyList배열을 DiaryList컴포넌트에 diaryList이름으로 prop전달

 

function App() {
  return (
    <div className="App">
      <DiaryEditor/>
      <DiaryList diaryList={dummyList}/>
    </div>

  );
}

 

 

 

전달 후 DiaryList 컴포넌트에서 prop 받기

 

 

 

정상적으로 받았는지 확인해보자

 

 

콘솔에는 일기 리스트 배열이 들어온 것을 확인 할 수 있고,

화면에는 일기의 개수(길이)를 확인 할 수 있다.

 

 

 

 

 

 


이제 배열을 List로 랜더링

div로 묶어준 후 

JSX표현식안에 map 내장함수를 사용한다. it으로 원소 순회하며 div를 출력해준다.

const DiaryList = ({diaryList}) => {
    console.log(diaryList);
    return (
    <div className="DiaryList">
        <h2>일기 리스트</h2>
        <h4>{diaryList.length}개의 일기가 있습니다.</h4>
        <div>
            {diaryList.map((it)=>(
                <div>
                    일기 아이템
                </div>
            ))}
        </div>
    </div>
    );
};

 

 

 

 

 

 

 

이번엔 it의 값을 넣어보자 (diaryList 하나하나의 요소가 it 파라미터로 들어옴)

const DiaryList = ({diaryList}) => {
    console.log(diaryList);
    return (
    <div className="DiaryList">
        <h2>일기 리스트</h2>
        <h4>{diaryList.length}개의 일기가 있습니다.</h4>
        <div>
            {diaryList.map((it)=>(
                <div>
                    <div>작성자 : {it.author}</div>
                    <div>글내용 : {it.content}</div>
                    <div>감정점수 : {it.emotion}</div>
                    <div>작성시간(ms) : {it.create_date}</div>
                    <hr/>
                </div>
            ))}
        </div>
    </div>
    );
};

export default DiaryList;

객체의 .표기법으로 작성자, 내용 등에 접근할 수 있다.

 

 

 

캡쳐가 어려워서 css에 값을 줬다.

.DiaryList {
  text-align: center;
}

 

 

 

 

 

 

만약 앱 컴포넌트 배열의 props를 받지못하고 undefined 상태라면?

TypeError: Cannot read properties of undefined(reading 'length')

DiaryList 컴포넌트의 6번째라인에 컴포넌트가 없다 라는 오류가 출력된다

 

이 때 필요한 것

 

 

 

 

defaultProps

undefined로 전달될 것 같은 props에 기본값을 설정해주어 오류 방지

DiaryList.defaultProps={
    diaryList:[]
}

 

그럼 이제 에러없이 dummyList 빈 배열을 랜더링 할 수 있다

 

 

 

 

 

 

 


Each child in a list should have a unique "key" prop. 에러해결

 

1. 컴포넌트에 key 값을 지정하기

 

 

 

 

2. index 순서를 지정해주기

 

 

 

idx는 변경 위험이 있으므로 고유 key를 넣어주는게 좋다

 

 

 

 


 

 

 

 

 

 

 

 

 

기존에 만든 DiaryList 배열을 별도의 컴포넌트로 분할

 

기존에 적어둔 diaryList 자식들을 지우고 

DiaryItem 컴포넌트를 추가해준다

 

 

                <DiaryItem key={it.id} {...it}/>

데이터를 받아야하기때문에 key를 추가해주고 스프레드 연산자를 통해 prop

아직은 마크업이 없기때문에 내용이 안뜨므로 

DiaryItem 컴포넌트로 가서 마크업을 주자

 

 

 

 

 

 

const DiaryItem = ({author, content, created_date, emotion, id})=>{
    return (
    <div className="DiaryItem">
        <div className="info">
            <span>
                작성자 : {author} | 감정점수 : {emotion} 
            </span>
            <br/>
            <span className="date">{new Date(created_date).toLocaleString()}</span>
        </div>
        <div className="content">{content}</div>
    </div>
    );
};

export default DiaryItem;

마크업 추가 후 css도 추가해주자

 

/* LIST */
.DiaryList {
  border: 1px solid gray;
  margin-top: 20px;
  padding: 20px;
}

.DiaryList h2 {
text-align: center;
}

.DiaryItem{
  background-color: rgb(240, 240, 240);
  margin-bottom: 20px;
  padding: 20px;
}

.DiaryItem .info{
  border-bottom: 1px solid gray;
  padding-bottom: 10px;
  margin-bottom: 10px;
}

.DiaryItem .date {
  color: gray;
}

.DiaryItem .content {
  font-weight: bold;
  margin: 30px 0;
}

 

 

 

출력결과

 

 

 

 

 

 

 

참고 :

- 한 입 크기로 잘라먹는 리액트

반응형
복사했습니다!