BioPlayground

🧬
목록으로

React로 실험 대시보드 만들기

React 컴포넌트, Props, State를 바이오 예제로 배웁니다. 유전자 카드, 시료 목록, 실험 대시보드를 만들며 React의 핵심을 이해합니다.

입문
|
75
|
검증 완료 (2026-06)
React컴포넌트PropsStateJSXUI 프레임워크
트랙 진행률0/11 (0%)

React로 실험 대시보드 만들기

지금까지 HTML로 구조를 잡고, JavaScript로 동작을 넣고, Node.js와 Express로 서버를 만들고, 데이터베이스에 실험 데이터를 저장하고 꺼내는 API까지 완성했습니다. 그런데 화면이 복잡해질수록 문제가 생깁니다. 유전자 정보 카드, 시료 목록, QC 결과 표, 필터 버튼 — 이 모든 것을 하나의 HTML 파일에서 innerHTML로 관리하면 코드가 금방 수천 줄이 됩니다.

React는 이 문제를 해결합니다. 나만의 HTML 태그를 만드는 기술입니다. <div><span> 같은 기본 태그 대신, <GeneCard>, <SampleList>, <QcDashboard> 같은 의미 있는 태그를 직접 만들어 씁니다. 실험실에서 복잡한 과정을 프로토콜 단위로 쪼개서 관리하듯, React는 UI를 컴포넌트 단위로 쪼개서 관리합니다.

컴포넌트: 나만의 태그 만들기

컴포넌트(Component)는 React의 핵심입니다. 함수 하나가 곧 태그 하나입니다:

javascript
function GeneCard() {
  return (
    <div>
      <h3>TP53</h3>
      <p>Chromosome: 17p13.1</p>
      <p>Function: tumor suppressor</p>
    </div>
  );
}

이 함수를 만들면 <GeneCard />라는 태그로 사용할 수 있습니다. 반드시 대문자로 시작해야 합니다 — React는 소문자로 시작하면 일반 HTML 태그, 대문자로 시작하면 사용자가 만든 컴포넌트로 구분합니다.

여러 컴포넌트를 조합해서 전체 화면을 구성합니다:

javascript
function App() {
  return (
    <div>
      <Header />
      <GeneCard />
      <SampleList />
    </div>
  );
}

App 함수 하나만 보면 이 화면이 Header, GeneCard, SampleList로 구성되어 있다는 것을 1초 만에 파악할 수 있습니다. 복잡한 HTML이 의미 있는 이름 뒤에 숨겨진 것입니다.

컴포넌트의 세 가지 장점:

  • 가독성: 코드의 구조가 한눈에 보입니다
  • 재사용성: <GeneCard />가 10곳에 필요하면 10번 쓰면 됩니다
  • 유지보수: 카드 디자인을 바꾸려면 GeneCard 함수 한 곳만 수정하면 모든 카드가 동시에 바뀝니다

Props: 컴포넌트에 데이터 넣기

위의 GeneCard는 항상 TP53만 보여줍니다. 다른 유전자도 보여주려면 Props(Properties의 약자)를 씁니다. 함수의 매개변수와 같은 개념입니다:

javascript
function GeneCard(props) {
  return (
    <div>
      <h3>{props.name}</h3>
      <p>Chromosome: {props.chromosome}</p>
      <p>Function: {props.geneFunction}</p>
    </div>
  );
}

function App() {
  return (
    <div>
      <GeneCard name="TP53" chromosome="17p13.1" geneFunction="tumor suppressor" />
      <GeneCard name="BRCA1" chromosome="17q21.31" geneFunction="DNA repair" />
      <GeneCard name="EGFR" chromosome="7p11.2" geneFunction="receptor tyrosine kinase" />
    </div>
  );
}

<GeneCard name="TP53" chromosome="17p13.1" />에서 name, chromosome, geneFunction이 Props입니다. React가 이 값들을 하나의 객체로 묶어서 함수의 첫 번째 매개변수(props)로 전달합니다.

JSX에서 중괄호 {}는 "여기는 JavaScript 영역"이라는 표시입니다. {props.name}이라고 쓰면 props 객체 안의 name 값이 출력됩니다. 중괄호 없이 props.name이라고 쓰면 그 글자 그대로 화면에 나옵니다.

실험 프로토콜로 비유하면 — GeneCard는 프로토콜 틀이고, Props는 그 틀에 넣는 시료입니다. 같은 프로토콜이지만 시료(데이터)에 따라 결과가 달라지는 것입니다.

리스트 렌더링: 배열 데이터를 컴포넌트로

시료가 3개가 아니라 100개라면 <GeneCard />를 100번 쓸 수 없습니다. 배열 데이터를 반복문으로 처리합니다:

javascript
function SampleList(props) {
  const items = [];

  for (let i = 0; i < props.samples.length; i++) {
    const sample = props.samples[i];
    items.push(
      <li key={sample.id}>
        {sample.id}: OD={sample.od} — {sample.status}
      </li>
    );
  }

  return (
    <ul>{items}</ul>
  );
}

function App() {
  const sampleData = [
    { id: "S001", od: 1.85, status: "pass" },
    { id: "S002", od: 0.42, status: "fail" },
    { id: "S003", od: 2.10, status: "pass" }
  ];

  return (
    <div>
      <h2>시료 QC 결과</h2>
      <SampleList samples={sampleData} />
    </div>
  );
}

몇 가지 주의점:

  • key={sample.id} — 반복으로 만든 요소에는 고유한 key를 줘야 합니다. React가 어떤 항목이 바뀌었는지 추적하는 데 사용합니다. 실험실에서 시료마다 고유 번호를 붙이는 것과 같습니다.
  • samples={sampleData} — Props로 배열을 전달할 때 중괄호로 감쌉니다. 문자열은 따옴표, JavaScript 값(배열, 숫자, 변수)은 중괄호입니다.

State: 변하는 데이터 관리하기

Props는 외부에서 받은 값이라 컴포넌트 안에서 바꿀 수 없습니다. 실험 조건서에 적힌 값을 중간에 마음대로 바꾸면 안 되는 것과 같습니다. 하지만 실험 진행 상태는 계속 바뀝니다 — "대기중" → "진행중" → "완료". 이런 내부 상태를 관리하는 것이 State입니다.

javascript
function ExperimentTracker() {
  const [status, setStatus] = React.useState("대기중");
  const [count, setCount] = React.useState(0);

  function handleStart() {
    setStatus("진행중");
    setCount(count + 1);
  }

  function handleComplete() {
    setStatus("완료");
  }

  return (
    <div>
      <p>실험 상태: {status}</p>
      <p>실행 횟수: {count}</p>
      <button onClick={handleStart}>실험 시작</button>
      <button onClick={handleComplete}>실험 완료</button>
    </div>
  );
}

React.useState("대기중")은 두 가지를 돌려줍니다:

  • status — 현재 값 ("대기중")
  • setStatus — 값을 바꾸는 함수

setStatus("진행중")을 호출하면 status가 바뀌고, React가 자동으로 화면을 다시 그립니다. innerHTML로 직접 DOM을 조작할 필요가 없습니다 — State만 바꾸면 화면이 알아서 갱신됩니다. 이것이 React의 가장 큰 장점입니다.

PropsState
방향외부에서 들어옴내부에서 관리
수정 가능불가 (읽기 전용)가능 (setState)
비유프로토콜에 적힌 실험 조건실험 진행 상태
예시유전자 이름, 염색체 위치"대기중" → "진행중" → "완료"

종합 예제: QC 대시보드

지금까지 배운 컴포넌트, Props, State를 합치면 간단한 QC 대시보드를 만들 수 있습니다:

javascript
function QcResult(props) {
  const style = {
    color: props.passed ? "green" : "red",
    fontWeight: "bold"
  };

  return (
    <tr>
      <td>{props.sampleId}</td>
      <td>{props.od}</td>
      <td style={style}>{props.passed ? "PASS" : "FAIL"}</td>
    </tr>
  );
}

function QcDashboard() {
  const samples = [
    { id: "S001", od: 1.85, passed: true },
    { id: "S002", od: 0.42, passed: false },
    { id: "S003", od: 2.10, passed: true },
    { id: "S004", od: 0.15, passed: false }
  ];

  const passCount = samples.filter(function(s) { return s.passed; }).length;

  return (
    <div>
      <h2>QC Dashboard</h2>
      <p>합격: {passCount} / {samples.length}</p>
      <table>
        <thead>
          <tr><th>시료 ID</th><th>OD</th><th>판정</th></tr>
        </thead>
        <tbody>
          {samples.map(function(s) {
            return <QcResult key={s.id} sampleId={s.id} od={s.od} passed={s.passed} />;
          })}
        </tbody>
      </table>
    </div>
  );
}

QcResult는 시료 한 건의 결과를 보여주는 컴포넌트, QcDashboard는 전체를 묶는 컴포넌트입니다. 데이터가 100건으로 늘어나도 QcResult 컴포넌트는 한 줄도 바꿀 필요 없습니다 — 데이터만 추가하면 됩니다.

직접 해보기 (Faded Example)

아래 빈칸을 채워 유전자 정보를 표시하는 React 컴포넌트를 완성하세요.

빈칸 채우기javascript
function GeneInfo() {
return (
<div>
<h3>{props.}</h3>
<p>Length: {.length_bp} bp</p>
</div>
);
}
// 사용: <GeneInfo name="TP53" length_bp={19149} />

흔한 에러 & 해결법

Q: 컴포넌트가 화면에 나타나지 않습니다

컴포넌트 이름이 소문자로 시작하면 React가 일반 HTML 태그로 인식합니다. geneCardGeneCard로 첫 글자를 대문자로 바꾸세요.

Q: Each child in a list should have a unique "key" prop 경고

반복문으로 만든 요소에 key prop이 없습니다. 배열의 각 항목이 가진 고유한 값(ID, 시료 번호 등)을 key로 지정하세요. 인덱스(i)를 key로 쓰는 것은 권장되지 않습니다.

Q: 중괄호와 따옴표를 언제 쓰는지 헷갈립니다

문자열은 따옴표: name="TP53". 숫자, 배열, 변수 등 JavaScript 값은 중괄호: count={42}, data={myArray}. JSX 안에서 JavaScript 코드를 실행하려면 중괄호로 감쌉니다: {props.name}.

Q: State를 직접 바꿨는데 화면이 안 바뀝니다

status = "완료" 처럼 직접 값을 바꾸면 React가 변경을 감지하지 못합니다. 반드시 setStatus("완료")처럼 setter 함수를 사용해야 React가 화면을 다시 그립니다.