React ) component, props, state연습 (feat. map)

bebrain·2022년 12월 9일
0
post-thumbnail

완성본

맨 위의 Header부분인 React를 클릭하면

<Article title="Hi!!!" body="Let's start"></Article>;

Article의 title과 body를 가져온다

Nav부분인 1. html~ 3. js를 클릭하면

  const details = [
    { id: 1, title: "html", body: "h내용입니다." },
    { id: 2, title: "css", body: "c내용입니다." },
    { id: 3, title: "js", body: "j내용입니다." },
  ];

클릭한 Nav의 id값이 details의 id와 같으면 그 id에 해당하는 객체의 title과 body값을 Article로 가져온다

<Article title={title} body={body}></Article>

전체코드

import "./App.css";
import { useState } from "react";

// useState : 태그의 상태를 변경시켜주는 리액트 hook

// 리액트는 속성을 prop이라고 한다

function Header(props) {
  /* Header를 props라는 객체로 만들어준것 */
  /* 리액트의 함수명 첫글자는 꼭 대문자로 */
  return (
    <header>
      <h1>
        <a
          href="/"
          onClick={(event) => {
            event.preventDefault(); //페이지 새로고침 방지
            props.onChangeMode();
          }}
        >
          {props.title}
        </a>
      </h1>
    </header>
  );
}
// 가운데 1.html 2.css 3.js
function Nav(props) {
  let lis = props.details.map((item) => {
    return (
      <li key={item.id}>
        <a
          id={item.id}
          // a id={item.id}를 넣지않아도 동작하는데 굳이 넣는이유? → 실제로 개발할 때 예시를 들면,
          // item.id라는 것은 스크롤을 내리면서 여러 군데를 봐야 이것이 뭘 의미하는 지 정확히 이해할 수 있습니다.
          // 하지만 event.target.id로 쓰게 되면 '바로 위에 있는 a태그의 id값을 나타내는 구나', 라고 바로 이해할 수 있습니다.

          //item.id를 가져올때는 숫자로 가져왔지만 태그의 속성으로 넘기면서 문자열이 된다

          href={"/read/" + item.id} //"/read/"는 왜 넣는걸까??? url
          onClick={(event) => {
            event.preventDefault();
            props.onChangeMode(Number(event.target.id));
            //item.id를 가져올때는 숫자로 가져왔지만 태그의 속성으로 넘기면서 문자열이 된다 → 숫자로 바꿔줌
          }}
        >
          {item.title}
        </a>
        {/* 리액트는 자동으로 생성하는 태그의 경우 추적을 위해 key라는 속성을 부여해줘야한다 */}
      </li>
    );
  });

  return (
    <nav>
      <ol>{lis}</ol>
    </nav>
  );
}
function Article(props) {
  return (
    <article>
      <h3>{props.title}</h3>
      {props.body}
    </article>
  );
}
function App() {
  // const total = useState('Hi');
  // const mode = total[0];
  // const setMode = total[1];
  
  const [mode, setMode] = useState("Hi"); // 이 코드는 위의 세줄과 같다
  //useState("Hi")를 console.log해보면 ['Hi', f(함수)]으로 나온다
  
  const [id, setId] = useState(null);
  
  const details = [
    { id: 1, title: "html", body: "h내용입니다." },
    { id: 2, title: "css", body: "c내용입니다." },
    { id: 3, title: "js", body: "j내용입니다." },
  ];

  let content = null;
  if (mode === "Hi") {
    content = <Article title="Hi!!!" body="Let's start"></Article>;
  } else if (mode === "Read") {
    //Article에 details의 body를 넣어줘야한다
    //여기서 id값은 Nav의 setId(idVal)값을 가져오는것이다
    //idVal값은 function Nav()의 <a id={item.id}></a>에서 가져온다
    let title,
      body = null;
    details.map((ele) => {
      if (ele.id === id) {
        title = ele.title;
        body = ele.body;
      }
      return (content = <Article title={title} body={body}></Article>);
    });
  }

  return (
    <div>
      {/* 컴포넌트 첫글자 대문자로 */}
      <Header
        title="React"
        onChangeMode={() => {
          setMode("Hi"); // 값을 바꿀때는 setMode를 사용
        }}
      ></Header>
      <Nav // 가운데 1.html 2.css 3.js 부분
        details={details}
        onChangeMode={(idVal) => {
          setMode("Read"); //Nav를 클릭했을때 mode값을 "Read"로 변경해준다
          setId(idVal); // Nav를 클릭했을때 그 클릭한 요소의 id값으로 id를 변경해준다
          //idVal값은 function Nav()의 <a id={item.id}></a>에서 가져온다
        }}
      ></Nav>
      {content}
    </div>
  );
}

export default App;

map() 사용시 주의할 점

📣 error가 났던 코드

let content = null;
  if (mode === "Hi") {
    content = <Article title="Hi!!!" body="Let's start"></Article>;
  } else if (mode === "Read") {
  
    let title, body = null;
    
    details.map((ele) => {
      if (ele.id === id) {
        title = ele.title;
        body = ele.body;
      }
    });
    
    return (content = <Article title={title} body={body}></Article>);
  }

map은 조건에 맞는 요소를 배열로 반환하는 함수인데 위의 코드를 보면
return값이 없다. 위의 코드에서는 return문이 details.map() 밖에 나와있고 map안에는 if문과 title, body에 대입하는 식만 존재함

📣 고친 코드

let content = null;
  if (mode === "Hi") {
    content = <Article title="Hi!!!" body="Let's start"></Article>;
  } else if (mode === "Read") {

    let title, body = null;
    
    details.map((ele) => {
      if (ele.id === id) {
        title = ele.title;
        body = ele.body;
      }
      return (content = <Article title={title} body={body}></Article>);
    });
  }

return문을 detail.map()안으로 옮겨주고 해결

0개의 댓글