React

React FAQ(자주 묻는 질문) 아코디언 기능

martinooo 2023. 3. 7. 13:53


 

리액트 & 타입스크립트를 활용해서 FAQ(자주 묻는 질문) 을 구현했다.

많은 웹사이트에서 활용되며 유기적으로 사이트로 유입시키고, 트랙픽 증가을 시키고자할 때 많이 사용된다.

사용자에게  정보를 제공할때 사용된다.

 

🙆‍♂️ 리액트 재렌더링 조건을 미리 숙지하고 있으면 이러한 기능을 만들때 유용하다. 

렌더링 조건

1. state(상태) 변경이 되었을때 렌더링 

2. 새로운 props가 전달될때 렌더링 

3. 기본 props가 업데이트될때 렌더링 

4. 페이지에 처음 들어올때 렌더링 

 



 

Github Source ☝ 구현 소스를 보실수 있습니다.

https://github.com/yoogukhyeon/react-camp

 

GitHub - yoogukhyeon/react-camp

Contribute to yoogukhyeon/react-camp development by creating an account on GitHub.

github.com


리액트 & 타입스크립트 설치  
npx create-react-app . --template typescript

 

App.tsx

import React, { useState } from 'react';
import { data } from './data';
import SingleQuestion from './Question';
function App() {
	// 데이터 셋한걸 useState에 상태관리
	const [question, setQuestion] = useState<any[]>(data);

	//클릭한 id값 useState에 상태관리
	const [index, setIndex] = useState<number>(0);

	return (
		<main>
			<div className="container">
				<h3>리액트 아코디언 기능</h3>
				<section className="info">
					{question.map((val) => (
						//components에 props 넘겨준다.
						<SingleQuestion key={val.id} setIndex={setIndex} index={index} {...val} />
					))}
				</section>
			</div>
		</main>
	);
}

export default App;

 

 

Question.tsx

import React, { Dispatch, useState } from 'react';
import { AiOutlineMinus, AiOutlinePlus } from 'react-icons/ai';

//type 정의
interface IProps {
	title: string;
	info: string;
	id: number;
	setIndex: Dispatch<React.SetStateAction<number>>;
	index: number;
}

const Question = ({ title, info, id, setIndex, index }: IProps) => {
	//toggle 상태 관리를 위해서 useState 상태관리
	const [toggle, setToggle] = useState<boolean>(false);

	//클릭시 toggle 상태를 바꿔주고 index에 현재 id 값 상태를 넣어준다.
	const onClickShow = (id: number) => {
		setToggle((prev) => !prev);
		setIndex(id);
	};

	return (
		<article className="question">
			<header>
				<h4>{title}</h4>
				<button className="btn" onClick={() => onClickShow(id)}>
					{!!toggle && id === index ? <AiOutlineMinus /> : <AiOutlinePlus />}
				</button>
			</header>
			{/* toggle 상태가 true고 id값하고 index값이 같은 info만 보이기  */}
			{!!toggle && id === index && <p>{info}</p>}
		</article>
	);
};

export default Question;