React 입문 (2)

보현·2022년 11월 19일
0

React

목록 보기
3/6

참고링크 - Seomal

🐶Create

🐮버튼 및 form 추가

🐰Create 버튼 추가

🔹App 컴포넌트 하단에 Create 버튼을 생성한다

<a href='/create' onClick={event => {
  event.preventDefault();
  setMode('CREATE');
}}>Create</a>

🔹state의 mode가 Create인 경우 Create 컴포넌트 호출한다

else if (mode === 'CREATE') {
  content = <Create></Create>
}

🦊Create 컴포넌트 생성

🔹Create 컴포넌트에 form 태그를 추가한다

// Article 컴포넌트 아님 주의...
function Create() {
  return (
  <article>
    <h2>Create</h2>
    <form>
      <p><input type='text' name='title' placeholder='title'/></p>
      <p><textarea name='body' placeholder='body'></textarea></p>
      <p><input type='submit' value='Create'/></p>
    </form>
  </article>
  )
}

🐻‍❄️Form의 Value값 Props로 넘기기

🔹Submit함수로 title과 body의 value값을 props로 넘긴다.

<form onSubmit={event => {
      event.preventDefault();
      const title = event.target.title.value;
      const body = event.target.body.value;
      props.onCreate(title, body);
    }}>

🐥리스트 배열에 값 추가하기

🔹onCreate에서 value들을 topics 배열에 담아서 리로드 시켜야하므로 topics를 state로 승격시킨다.

const [topics, setTopics] = useState([
    {id: 1, title: 'html', body: 'html is ...'},
    {id: 2, title: 'css', body: 'css is ...'},
    {id: 3, title: 'javascript', body: 'javascript is ...'},
  ])

🔹topics에 저장할 id값을 위해 nextId state를 추가해준다
🔹그리고 nextId를 새로 저장할 id값으로 사용한다

// 이미 배열에 3개 들어있으므로 초기값 4로 지정
const [nextId, setNextId] = useState(4);
else if (mode === 'CREATE') {
    content = <Create onCreate={(_title, _body) => {
      const newTopic = {id: nextId, title: _title, body: _body}
    }}></Create>
  }

객체값을 state상태인 배열에 추가로 넣으려면 추가하려는 배열을 복제해서 새 배열을 만들고,
거기에 추가하려는 배열을 push 해 줘야한다.
( 객체면 {...newValue}, 배열이면 [...newValue] 형식으로 복제한다 )
그리고 state를 리로드 해 준다.

else if (mode === 'CREATE') {
    content = <Create onCreate={(_title, _body) => {
      const newTopic = {id: nextId, title: _title, body: _body}
      const newTopics = [...topics]
      newTopics.push(newTopic);
      setTopics(newTopics);
    }}></Create>
  }

🔼 그러면 이렇게 작성한 값이 배열에 추가되는데 좀 더 세련된 작업을 위해 create 후에 해당 값의 상세페이지로 로드 해 준다.

else if (mode === 'CREATE') {
    content = <Create onCreate={(_title, _body) => {
      const newTopic = {id: nextId, title: _title, body: _body}
      const newTopics = [...topics]
      newTopics.push(newTopic);
      setTopics(newTopics);
      setMode('READ');
      setId(nextId);
      setNextId(nextId+1);
    }}></Create>
  }

🔼 그럼 요로케 Create 후 해당 값의 상세페이지로 로드가된다.
끗 - 😎

🔻 전체코드

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

function Header(props) {
  return (
    <header>
      <h1>
        <a href="/" onClick={(event) => {
          event.preventDefault();
          props.onChangeMode();
        }}>{props.title}</a>
      </h1>
    </header>
  );
}
function Nav(props) {
  const lis = []
  for (let i = 0; i < props.topics.length; i++) {
    let t = props.topics[i]
    lis.push(
      <li key={t.id}>
        <a id={t.id} href={'/read/'+t.id} onClick={(event) => {
          event.preventDefault();
          props.onChangeMode(Number(event.target.id));
        }}>{t.title}</a>
      </li>
    )
  }
  return (
    <nav>
      <ol>
        {lis}
      </ol>
    </nav>
  );
}
function Article(props) {
  return (
    <article>
      <h2>{props.title}</h2>
      {props.body}
    </article>
  );
}

function Create(props) {
  return (
  <article>
    <h2>Create</h2>
    <form onSubmit={event => {
      event.preventDefault();
      const title = event.target.title.value;
      const body = event.target.body.value;
      props.onCreate(title, body);
    }}>
      <p><input type='text' name='title' placeholder='title'/></p>
      <p><textarea name='body' placeholder='body'></textarea></p>
      <p><input type='submit' value='Create'/></p>
    </form>
  </article>
  )
}

function App() {
  const [mode, setMode] = useState('WELCOME');
  const [id, setId] = useState(null);
  const [nextId, setNextId] = useState(4);
  const [topics, setTopics] = useState([
    {id: 1, title: 'html', body: 'html is ...'},
    {id: 2, title: 'css', body: 'css is ...'},
    {id: 3, title: 'javascript', body: 'javascript is ...'},
  ])
  let content = null;
  if (mode === 'WELCOME') {
    content = <Article title='Welcome' body='Hello WEB~'></Article>
  } else if (mode === 'READ') {
    let title, body = null;
    for (let i = 0; i < topics.length; i++) {
      if (topics[i].id === id) {
        title = topics[i].title;
        body = topics[i].body;
      }
    }
    content = <Article title={title} body={body}></Article>
  } else if (mode === 'CREATE') {
    content = <Create onCreate={(_title, _body) => {
      const newTopic = {id: nextId, title: _title, body: _body}
      const newTopics = [...topics]
      newTopics.push(newTopic);
      setTopics(newTopics);
      setMode('READ');
      setId(nextId);
      setNextId(nextId+1);
    }}></Create>
  }
  return (
    <div className="App">
      <Header title='WEB' onChangeMode={() => {
        setMode('WELCOME');
      }}></Header>
      <Nav topics={topics} onChangeMode={(_id) => {
        setMode('READ');
        setId(_id);
      }}></Nav>
      {content}
      <a href='/create' onClick={event => {
        event.preventDefault();
        setMode('CREATE');
      }}>Create</a>
    </div>
  );
}

export default App;
profile
하고싶은거 하는 개발자

0개의 댓글