본문 바로가기
Dev/React

[React] UI 업데이트 State Hooks

by Ellen571 2024. 7. 9.
반응형

 

function App() {
  let tabContent = 'Please click a button';

  function handleSelect(selectedButton) {
    tabContent = selectedButton;
    console.log(tabContent);
  }

  return (
  <section id="examples">
    <menu>
      <TabButton onSelect={() => handleSelect("components")}>
        Components
      </TabButton>
      <TabButton onSelect={() => handleSelect("jsx")}>JSX</TabButton>
      <TabButton onSelect={() => handleSelect("props")}>Props</TabButton>
      <TabButton onSelect={() => handleSelect("state")}>State</TabButton>
    </menu>
    {tabContent}
  </section>
  );
}
  • 버튼을 클릭하면 tabContent 변수가 handleSelect에 의해 업데이트되나 UI가 업데이트되지 않는다.
  • 이유는 클릭한다해서 App 컴포넌트 함수가 다시 실행되지 않아서이다.
  • By Default, React Components Execute Only Once
  • You have to tell React if a component should be executed again
  • 앱 함수는 재실행되지 않기 때문에 모든 JSX코드가 재평가 되지 않는다.
  • 리액트에 변화를 알려주고 업데이트를 하기 위해 state가 필요하다.

 

useState

리액트에서 처리되는 변수를 등록하는 것이며 리액트가 제공하는 함수의 도움을 받아 업데이트된다.

import { useState } from ‘react’;
  • useState는 리액트 Hook이다.
  • 리액트 프로젝트에서 ‘use’로 시작하는 모든 함수를 리액트 Hooks라고 한다.

 

 

Hooks

일반 함수이지만 특별한 점은 컴포넌트 함수 또는 다른 리액트 Hook 안에서 실행되어야 한다는 점이다.

// useState() X
function App() {
	useState();
	function abc() {
		// useState() X
	}
	if ( ... ) {
		// useState() X
	}
}
  • Hook 함수는 컴포넌트 함수 안에서 바로 호출해야 하기에 컴포넌트 최상위에 위치해야 한다.
  • 다른 코드 안에 중첩되면 안된다. if문 loop도 안된다.

 

 

useState()

const [selected, setSelected] = useState('Please click a button')
  • useState는 인수로 컴포넌트가 처음 렌더링될 때 사용하길 원하는 기본값을 받는다. ('Please click a button')
  • 그러면 useState는 값을 반환하는데 이는 변수 또는 상수에 저장할 수 있다. const
  • 반환되는 이 값은 배열이다.
  • 이 배열에는 요소가 2가지가 있다.
  • 첫번째 요소는 컴포넌트가 처음 실행될 때 초기 값이 저장된다.  selected
  • 두번째 요소는 함수로 초기값 상태를 업데이트하기 위해 실행되어 첫번째 요소 값을 업데이트한다. setSelected
  • 두번째 요소인 이 특수 함수를 호출하면 리액트에 해당 컴포넌트 함수를 다시 실행해야 함을 알려준다.
  • 그렇기 때문에 const를 사용할 수 있는데 selected와 같은 상수가 컴포넌트 함수를 실행할 때마다 다시 생성되기 때문이다.
function App() {
  const [selected, setSelected] = useState('Please click a button')

  function handleSelect(selectedButton) {
    setSelected(selectedButton);
  }

  return (
    <menu>
      <TabButton onSelect={() => handleSelect("components")}>Components</TabButton>
      <TabButton onSelect={() => handleSelect("jsx")}>JSX</TabButton>
      <TabButton onSelect={() => handleSelect("props")}>Props</TabButton>
      <TabButton onSelect={() => handleSelect("state")}>State</TabButton>
    </menu>
    {selected}
  );
}

 

 

 

외부 데이터 활용

import { EXAMPLES } from "./data.js"

function App() {
  const [selected, setSelected] = useState('components');

  function handleSelect(selectedButton) {
    setSelected(selectedButton);
  }

	return (
    <menu>
      <TabButton onSelect={() => handleSelect("components")}>Components</TabButton>
      <TabButton onSelect={() => handleSelect("jsx")}>JSX</TabButton>
      <TabButton onSelect={() => handleSelect("props")}>Props</TabButton>
      <TabButton onSelect={() => handleSelect("state")}>State</TabButton>
    </menu>
    <div id="tab-content">
      <h3>{EXAMPLES[selected].title}</h3>
      <p>{EXAMPLES[selected].description}</p>
      <pre>
        <code>{EXAMPLES[selected].code}</code>
      </pre>
    </div>
  );
}
  • 객체 속성
    • 객체는 키와 값으로 구성된 속성(프로퍼티)들의 집합이다.
    • 속성의 값이 함수일 경우 일반 함수와 구분하기 위해 메소드라고 부른다.
  • 객체 속성 접근 방법
    • 키가 유효한 자바스크립트 이름이고 예약어가 아닌 경우 []대괄호, .마침표 모두 사용한다.
var person = {
  'first-name': 'Mark',
  'last-name': 'Kim',
  gender: 'male',
  1: 10
};

console.log(person);

console.log(person.first-name);    // NaN: undefined-undefined
console.log(person[first-name]);   // ReferenceError: first is not defined
console.log(person['first-name']); // 'Mark'

console.log(person.gender);    // 'male'
console.log(person[gender]);   // ReferenceError: gender is not defined
console.log(person['gender']); // 'male'

console.log(person['1']); // 10
console.log(person[1]);   // 10 : person[1] -> person['1']
console.log(person.1);    // SyntaxError
  • 점 표기법은 따옴표를 붙이지 않아도 된다. person.gender
  • 대괄호 표기법은 따옴표를 붙여야한다. person['gender']
  • 점 표기법은 여러 단어로 이뤄진 속성에는 사용할 수 없다. car.goes fast // error
  • 대괄호 표기법은 키를 사용해서 속성에 접근할 때이다.

 

 

조건적 콘텐츠 렌더링

초기에 원하는 문구가 나오고 주제 선택 시 데이터 나오게 하기

function App() {
  const [selected, setSelected] = useState();

  function handleSelect(selectedButton) {
    setSelected(selectedButton);
  }

  return (
    <menu>
      <TabButton onSelect={() => handleSelect("components")}>Components</TabButton>
      <TabButton onSelect={() => handleSelect("jsx")}>JSX</TabButton>
      <TabButton onSelect={() => handleSelect("props")}>Props</TabButton>
      <TabButton onSelect={() => handleSelect("state")}>State</TabButton>
    </menu>
    {!selected ? (<p>Please select a topic.</p>
    ) : (
    	<div id="tab-content">
          <h3>{EXAMPLES[selected].title}</h3>
          <p>{EXAMPLES[selected].description}</p>
          <pre>
            <code>{EXAMPLES[selected].code}</code>
          </pre>
        </div>
     )}
  );
}
  • useState 초기값을 비운다
  • !selected ? (<p>Please select a topic.</p>)
    • selected가 비어있으면
    • !selected
      • selected === undefined(정의되지 않음)
  • : (…)
    • 선택된 주제가 있으면 내용을 보여준다.

 

 

&& AND 연산자 활용

function App() {
  const [selected, setSelected] = useState();

  function handleSelect(selectedButton) {
    setSelected(selectedButton);
  }

  return (
    <menu>
      <TabButton onSelect={() => handleSelect("components")}>Components</TabButton>
      <TabButton onSelect={() => handleSelect("jsx")}>JSX</TabButton>
      <TabButton onSelect={() => handleSelect("props")}>Props</TabButton>
      <TabButton onSelect={() => handleSelect("state")}>State</TabButton>
    </menu>
    {!selected && <p>Please select a topic.</p>}
    {selected && (
    	<div id="tab-content">
          <h3>{EXAMPLES[selected].title}</h3>
          <p>{EXAMPLES[selected].description}</p>
          <pre>
            <code>{EXAMPLES[selected].code}</code>
          </pre>
        </div>
     )}
  );
  • &&는 왼쪽, 오른쪽 모두 참이여야 오른쪽 코드를 출력한다.

 

 

변수로 분리하기

function App() {
  const [selected, setSelected] = useState();

  function handleSelect(selectedButton) {
    setSelected(selectedButton);
  }
  
  let tabContent = <p>Please select a topic.</p>;
  
  if(selected) {
    tabContent = (
        <div id="tab-content">
          <h3>{EXAMPLES[selected].title}</h3>
          <p>{EXAMPLES[selected].description}</p>
          <pre>
            <code>{EXAMPLES[selected].code}</code>
          </pre>
        </div>
    )
  }

  return (
    <menu>
      <TabButton onSelect={() => handleSelect("components")}>Components</TabButton>
      <TabButton onSelect={() => handleSelect("jsx")}>JSX</TabButton>
      <TabButton onSelect={() => handleSelect("props")}>Props</TabButton>
      <TabButton onSelect={() => handleSelect("state")}>State</TabButton>
    </menu>
    {tabContent}
  );

 

반응형