티스토리 뷰

▶홈화면 게시물 - 데이터베이스에서 가져와서 컴포넌트로 보여주기

홈화면에 게시물들을 나타낼 겁니다.

데이터베이스에 저장되어 있는 게시물 정보를 가져와서 하나씩 컴포넌트로 화면에 보여주려고 합니다.

 

📌 홈화면 화면 구성

홈화면 화면 구성

 

📌 해야하는 연결

데이터베이스에 연결하여 home 테이블에서 데이터를 모두 가져와 row 하나당 CardBox라는 컴포넌트 하나씩 화면에 보여주려고 합니다.

 

📌 홈화면 컴포넌트

가장 먼저 홈화면 컴포넌트를 구성하려고 합니다.

밑에서 CardBox라는 컴포넌트를 만들어서 화면에 보여줄 것까지 알고 코드를 봐 봅시다.

 

📄 Home.jsx 파일

export default function Home(props) {
  const [array, setArray] = useState([]);

  useEffect(() => {
    axios.get('/api/home').then((res) => {
      setArray(res.data.result);
    });
  }, []);

  const onRefreshHome = () => {
    console.log('onrefresh call');
    axios.get('/api/home').then((res) => {
      setArray(res.data.result);
    });
  };

  return (
    <>
      <Header name="home" />

      <section className="home-layer">
        <ul className="list">
          {array &&
            array.map((item, index) => {
              return (
                <CardBox
                  key={item.homeid}
                  value={item}
                  onRefresh={onRefreshHome}
                />
              );
            })}
        </ul>
      </section>
    </>
  );
}

데이터베이스에서 모든 row를 받아와 담을 배열인 array를 useState를 이용하여 선언해 주었습니다.

useEffect를 사용하여 컴포넌트가 처음 렌더할 때 실행되고 다시는 실행되지 않게 할 api 통신 코드를 작성해 주었습니다.

 

이제 useEffect를 통해 컴포넌트가 처음 렌더되었을 때 데이터를 받아와 array에 넣어줄 것입니다.

이 array는 밑에서 CardBox 라는 자식 컴포넌트에 보내 하나씩 화면에 보여주게 될 것입니다 :)

 

자세히 살펴볼 점은,

지금 데이터베이스에서 받은 데이터를 객체 형태 통째로 하나씩 array에 집어넣었습니다.

 

📌 게시물 컴포넌트 - CardBox

CardBox라는 컴포넌트를 만들어서 데이터베이스에서 받는 데이터 리스트를 map 하여 화면에 출력하려고 합니다.

 

CardBox 컴포넌트는 부모 컴포넌트인 Home 컴포넌트가 준 값들을 받아 화면에 출력하는 역할만 잘 하면 됩니다.

(좋아요, 댓글달기 기능은 다음 포스팅에서 다룰 예정입니다!)

 

📄 Home.jsx 파일

// ...

const CardBox = (props) => {
  const { homeid, likecount, title, subtitle, tags, url, text, image } = props.value;
  
  return (
    <li>
      <div className="card">
        <div className="head">
          <div>
            <Image src={EDU_ICON} alt="광고 아이콘" />
            <span className="title">{title}</span>
            <Image className="more" src={MORE_ICON} alt="더보기 메뉴" />
          </div>
          <div className="text">
            <p>{subtitle}</p>
            <p className="blue">{tags}</p>
          </div>
        </div>
        <div className="body">
          <div className="image">
            <Image src={image} />
          </div>
          <div className="text">
            <div>
              <p className="grey sm">{url}</p>
              <p className="bold">{text}</p>
            </div>
            <button>더 알아보기</button>
          </div>
        </div>
        <div className="foot">
          <div className="btn-box active">
            <div>
              <Image src={HOME_ICON} alt="홈 바로가기" />
              <span className="btn-text" onClick={onClickLike}>
                좋아요({likecount})
              </span>
            </div>
          </div>
          <div className="btn-box">
            <div>
              <Image src={YOUTUBE_ICON} />
              <span className="btn-text" onClick={onClickComment}>
                댓글 달기
              </span>
            </div>
          </div>
          <div className="btn-box">
            <div>
              <Image src={PEOPLE_ICON} />
              <span className="btn-text">공유 하기</span>
            </div>
          </div>
        </div>
      </div>
    </li>
  );
};
}

 

📌 src/api/index.js

방금 클라이언트가 api/home으로 get 요청을 보냈으니 맞춰서 서버에서도 코드를 추가해 줍니다.

 

📄 src/api/index.js 파일

router.get('/home', async (req, res) => {
  const array = await mysql.selectHome();
  res.send({result: array});
});

전 포스팅과 비슷하게 marai.js 파일로 가서 selectHome이라는 메서드에 쿼리문을 포함하여 정의해 주면 끝입니다!

 

📌 src/api/maria.js 파일

home 테이블에서 모든 데이터를 가져오는 쿼리문을 포함한 메서드인 selectHome을 정의해 줍시다.

 

📄 src/api/maria.js 파일

Maria.selectHome = (params) => {
  return new Promise(async (resolve) => {
    const sql = `select * from home;`;
    const result = await queryFunc(sql);
    resolve(result);
  });
};

 

📌 데이터베이스 사진 파일에 대해

사진은 보통 서버에서 가지고 있거나 url을 통해 보여주는데요.

서버에서 가지고 있는 경우에 대해서 이야기 해보려고 합니다.

 

제일 처음에 파일 구성할 때 미들웨어를 설정한다고 하면서 server.js 파일에 다음과 같은 코드를 추가했었습니다.

app.use(express.static(path.join(__dirname, 'public')));

 

우선 static이라는 키워드가 보입니다.

이는 정적 파일을 의미하는데요.

정적 파일이란, 직접 값에 변화를 주지 않는 이상 변하지 않는 파일을 의미합니다.

예를 들면, images, css파일, js 파일 등이 있습니다.

express는 이러한 정적 파일들을 손쉽게 제공할 수 있는 기능을 가지고 있습니다.

 

위 코드로 다시 돌아와서,

express.static는 미들웨어로서 로드를 해주는 역할을 하게 됩니다.

static의 인자로 전달되는 public은 폴더의 이름입니다.

 

따라서 public 이라는 폴더 밑에 있는 데이터들은 웹브라우저의 요청에 따라 서비스를 제공해 줄 수 있게 됩니다.

쉽게 말해, 클라이언트가 public이라는 폴더의 자료들에 모두 접근이 가능하다는 말과도 같습니다.

 

따라서 저는 본 프로젝트에서 홈화면에 표시해줄 이미지 데이터를 public이라는 폴더 아래에 저장해 두었는데요.

미들웨어에 public이라는 폴더를 설정해 주었기 때문에

데이터베이스에 image라는 컬럼에는 '/images/game-1.jpg' 와 같이 저장하고 있으면 됩니다.

데이터베이스에 입력한 image 컬럼의 값들

 

728x90
LIST
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함