22-11-15-리액트(4)

YJ·2022년 11월 15일
0
post-thumbnail

컴포넌트 리스트

map 함수를 이용하여 많은 데이터를 한번에 생성할 수 있다.

[리스트].map(i => {return 로직})
function Hello(props) {
	const name = props.name;
  	const num = [1,2,3,4,5,6,7,8,9,10];
  	const numComponentsArray = num.map(i => <h1>안녕 {i}</h1>);
	return (
    	<div>
      		{numComponentsArray}
      	</div>
    )
}

키 값 부여하기

컴포넌트 안에서 리스트 렌더링할 때는 리스트 고유의 key 값을 부여해야 한다.
어떤 요소의 변동이 있다면 해당하는 요소만 변경시켜주기 위해 key 값이 필요
key 값은 일반적으로 배열의 id 값을 넣어준다.
인덱스 값으로 사용하기에는 권장하지 않음

const numComponentsArray = num.map(i => (
	<h1 key={i.toString()}>안녕 {i}</h1>
))
  • 직접 배열에 넣기
function App() {
  return (
    <div>
      {/* 다중 배열인 경우 중복된 key값을 가지고 있으면 안됩니다. */}
      {[
        <One key='100'/>,
        <Two  key='200'/>,
        <Three  key='300'/>, 
        [
          <One  key='400'/>,
          <Two  key='500'/>,
          [
            // 나와 같은 컴포넌트가 동일한 키를 가지고 있으면 Error
            <One  key='600'/>,
            // 나와 다른 컴포넌트가 동일한 키를 가지고 있으면 Error가 나진 않습니다.
            <Two  key='100'/>,
          ]

      ]]}
    </div>
  );
}
function solution(productList) {
	let result = [];
  	for (const item of productList) {
    	result.push(
        	<section key={item.id}>
          		<h2>
          			{item.title}
          		</h2>
          		<p>{item.price}</p>
          	</section>
        )
    }
	return result;
} 
export default function App() {
	return (
    	<div>
      		{solution(productList.products)}
      	</div>
    )
}

조건부 렌더링

조건에 따라 다른 페이지 렌더링

// App.js
import {useState} from 'react'

function Contents({listName}) {
	if(listName === 'about') {
    	return (<div>loremloremlorem</div>)
    } else if (listName === 'product') {
        return (<div>loremloremlorem</div>)
    }
  	return (<div>404 페이지를 찾을 수 없습니다.</div>)
}

function Navbar() {
	const [listName, setListName] = useState('about');
  	const handleChangeId = (e) => {
    	setListName(e.target.id)
    }
    return (
    	<>
      		<nav>
      			<ul>
      				<li id = 'about' style={listName === 'about'?{color:'red'}:{color:'black'}} onClick={handleChangeId}> 
      					About
      				</li>
					<li id = 'product' style={listName === 'product'?{color:'red'}:{color:'black'}} onClick={handleChangeId}> 
      					About
      				</li>
      			</ul>
      		</nav>
			<Contents listName={listName}/>
      	</>
    )
}

export default function App() {
	return (
    	<div>
      		<Navbar></Navbar>
      	</div>
    )
}

스타일 적용하기

styled-components

인기 있는 리엑트 라이브러리

npm install styled-components

글로벌 스타일

styled-components가 제공하는 createGlobalStyle() 함수를 사용
전역으로 함수 생성 (상단) -> 모든 하위 컴포넌트에 스타일이 적용

import {createGlobalStyle} from 'styled-components'

const GlobalStyle = createGlobalStyle`
span {
	color : red;
}
`
function App() {
	return (
    	<>
      		<GlobalStyle/>
      		<h1>hello world</h1>
      	</>
    )
}

Reset css

npm i styled-reset
  • 글로벌 스타일에 reset 적용하기
import {createGlobalStyle} from 'styled-components'
import reset from 'styled-reset'

const GlobalStyle = createGlobalStyle`
${reset}
span {
	color : red;
}
`
function App() {
	return (
    	<>
      		<GlobalStyle/>
      		<h1>hello world</h1>
      	</>
    )
}

스타일 적용하기

styled-components를 적용하려면 하이픈 표기법으로 프로퍼티를 작성

import styled from 'styled-components';

const 변수명 = styled.태그명`
	background-color : red;
`
const 변수명 = styled.태그명`
	background-color : red;
`
const App = () => {
	return (
    	<변수명>Hello</변수명>
    )
}

props에 따른 스타일 적용

${}에 코드 입력

import React from 'react';
import styled from 'styled-components';

const ContentH2 = styled.h2`
	color: ${(props) => (props.name === 'hello' ? 'red' : 'black')}
	width: 200px
`
const App = () => {
	return (
    	<ContentH2 name = 'hello'>hi</ContentH2>
    )
}
export default App;

확장해서 사용하기

import React from 'react';
import styled from 'styled-components';

const ContentH2 = styled.h2`
	color: ${(props) => (props.name === 'hello' ? 'red' : 'black')}
	width: 200px
`
const ContentThree = styled(ContentH2)`
	border: 1px solid black;
`
const Two = styled.div`
	font-size: ${props => props.size + 'px'}
`
const App = () => {
	return (
      <div>
    	<ContentH2 name = 'hello'>hi</ContentH2>
    	<ContentThree>hiii</ContentThree>
      	<Two size={60}>hello</Two>
      </div>
    )
}
export default App;

module.css

부모 컴포넌트에서 import한 css는 자식까지 자동으로 적용
module.css를 사용하면 class명에 고유값을 추가해주어서 겹치지 않도록 한다.

해당 컴포넌트가 아닌 상위, 하위 컴포넌트에 영향을 주는 것을 막기 위해 css 파일 이름을 module.css로 변경하기
ex) Question.module.css

{styles.클래스명} 로 변경

const App = () => {
	return (
      <div>
    	<h2 className={styles.text}>hii</h2>
      </div>
    )
}

0000.module.css 로 파일명을 추가하고 styles.클래스명 으로 한다면 자동으로 클래스명이 겹치지않게 처리

합성 컴포넌트

일반적인 컴포넌트 하나 만들고 그 안의 세부기능을 합성하여 사용함으로써 컴포넌트의 재사용성을 높임
ex) 모달 창 -> 중복되는 부분 재사용하기
styled-components를 사용

props.children 이라는 속성을 통해 자식으로 사용되는 부분을 표현

  • 합성 컴포넌트 사용하기
import styled from 'styled-components';

const CardDiv = styled.div`
	padding: 20px;
	width: ${props => (props.className === 'setting'? '200px':'400px')};
`;

const Card = (props) => {
	return (
    	<CardDiv className={props.className}>
      		<h3>{props.value}</h3>
      		<hr/>
      		{/* props.children 속성으로 컴포넌트 합쳐주기 */}
			<div>{props.children}</div>
      	</CardDiv>
    )
}
const SettingCard = () => {
	return (
      <>
    	<button>초기화</button>
    	<button>저장하기</button>
      </>
    )
}
const ShardCard = () => {
	retur (
    	<>
      		<p>loremloremlorem</p>
      		<div>
                <button>저장</button>
                <button>000</button>
      		</div>
      	</>
    )
}

function App() {
	return (
    	<>
      		<Card className='setting' value='설정'>
      			<SettingCard/>
      		</Card>
      		<Card className='share' value='공유하기'>
      			<ShardCard/>
      		</Card>
      
      	</>
    )
}
export default App;

Card 컴포넌트 사이에 들어가는 {props.children} 가 자식 요소를 받아옴

profile
함께 배워나가고 싶습니다!

0개의 댓글