import React from 'react';
import Todo from './Todo';
import './styles.css';
const DUMMY_TODOS = [
'Learn React',
'Practice React',
'Profit!'
];
// don't change the Component name "App"
export default function App() {
return (
<ul>
Todo: Output todos
</ul>
);
}
“할 일 목록” 웹 앱을 만든다고 해봅시다. 여러분이 해야 할 작업은 더미 할 일 항목의 목록을 동적으로 출력하는 것입니다. 이 작업에 대해 Todo
컴포넌트가 준비되어 있지만, 할 일 텍스트를 수신하고 출력하기 위해서는 여전히 코드를 좀 더 추가해야 합니다.
더 정확히 말하면, App
컴포넌트에서 제공된 DUMMY_TODOS
배열(변경해서는 안 됩니다!)을 JSX 요소 목록(정확히 말하면 <Todo>
요소)으로 변환해야 합니다. 모든 할 일 컴포넌트 항목은 text
라는 prop을 통해 할 일 텍스트를 수신하고 출력해야 합니다.
내 코드 (PASS)
// App.js
import React from 'react';
import Todo from './Todo';
import './styles.css';
const DUMMY_TODOS = [
'Learn React',
'Practice React',
'Profit!'
];
// don't change the Component name "App"
export default function App() {
return (
<ul>
{DUMMY_TODOS.map((todo) => (<Todo text={todo}/>))}
</ul>
);
}
// Todo.js
import React from 'react';
export default function Todo({text}) {
return <li>{text}</li>;
}
setUserList(prevState => ([...prevState, userData]);
key
를 지정해서 고유한 인덱스 역할을 할 수 있게 해줘야 함.const App = () => {
const [productList, setProductList] = useState([]);
const [filteredYear, setFilteredYear] = useState(2020); // default;
const onChangeFilter = (selectedOption) => {
setFilteredYear(selectedOption);
filteredProductList(
}
const filteredProductList = productList.filter((product) => product.date.getFullYear().toString() === filteredYear);
return (
<YearFilter filteredYear={filteredYear} onChangeFilter={onChangeFilter} />
<ProductList productList={filteredProductList} filteredYear={filteredYear}/>
);
}
const YearFilter = ({filteredYear, onChangeFilter}) => {
const handleChange = (e) => {
onChangeFilter(e.target.value);
}
return (
<select value={filteredYear} onChange={handleChange}>
...
</select>
);
}
const ProductList = ({productList}) => {
return (
{
productList.map((product) => (
<div key={product.id}>
<div>{product.title}</div>
<div>{product.price}</div>
<div>{product.date}</div>
</div>
));
}
);
}
방법 1
- JSX 코드가 복잡해질 수 있음.
const Component = () => {
...
return (
{filteredData.length === 0 && <p>No Data Found.</p>}
{filteredData.length > 0 && filteredData.map((data) => (...))}
)
}
방법 2
- JSX를 let 변수로 저장해서 조건문으로 재할당 가능하게
- 이 방법으로 작성 시 가독성 좋게 표현 가능하다. (취향대로 하면 OK)
const Component = () => {
...
let dataContent = <p>No Data Found.</p>;
if (filteredData.length > 0) {
dataContent = filteredData.map((data) => (...));
}
return (
{dataContent}
)
}
사용자가 위험한 작업을 수행하려고 할 때 경고를 표시하는 웹 앱을 만들고 있다고 가정해 보겠습니다.
따라서, 여러분이 해야 할 작업은 사용자가 특정 버튼을 클릭하면 조건에 따라 경고 상자를 표시하는 것입니다. 경고 대화 상자 안에는 사용자가 경고를 해제(즉, 화면에서 경고 상자를 제거)할 수 있는 다른 버튼이 있습니다.
<button>
을 클릭하지 않은 경우, 완성된 앱에는 이 UI가 표시되어야 합니다:
버튼을 클릭한 경우에는 이 UI가 표시됩니다:
“진행” 버튼을 클릭하면 경고 상자가 다시 삭제되어야 합니다:
이 작업에서는, 시작 코드에 있는 두 <button>
요소의 클릭에 모두 반응해야 합니다. 두 번째 버튼은 id="alert"
가 있는 <div>
외부에 <div id="alert">
(및 모든 콘텐츠)를 표시해야 합니다.
삼항 표현식을 사용할지, 조건에 따라 표시되는 JSX 코드를 변수에 저장할지는 사용자가 결정할 수 있습니다.
중요. Udemy 코드 편집기에서는 useState()
를 쓰면 에러가 생길 수 있으므로 useState()
가 아니라 React.useState()
을 사용해야 합니다!
내 코드 (PASS)
import React from 'react';
// don't change the Component name "App"
export default function App() {
const [isAlertOpen, SetIsAlertOpen] = React.useState(false);
const openAlert = () => {
SetIsAlertOpen(true);
}
const closeAlert = () => {
SetIsAlertOpen(false);
}
return (
<div>
{
isAlertOpen && (
<div id="alert">
<h2>Are you sure?</h2>
<p>These changes can't be reverted!</p>
<button onClick={closeAlert}>Proceed</button>
</div>
)
}
<button onClick={openAlert}>Delete</button>
</div>
);
}
const dataPoints = [
{
id: 1,
value: 293103,
},
{
id: 2,
value: 23525434,
},
{
id: 3,
value: 123232,
},
{
id: 4,
value: 999999999,
}
];
const dataPointValues = dataPoints.map(dataPoint => dataPoint.value);
const maxValue = Math.max(...dataPointValues);
let barFillHeight = value / maxValue * 100 + '%';
...
<div style={{height: barFillHeight}}></div>
const chartDataPoints = [
{label: 'Jan', value: 0},
{label: 'Feb', value: 0},
{label: 'Mar', value: 0},
{label: 'Apr', value: 0},
{label: 'May', value: 0},
{label: 'Jun', value: 0},
{label: 'Jul', value: 0}
{label: 'Aug', value: 0},
{label: 'Sep', value: 0},
{label: 'Oct', value: 0},
{label: 'Nov', value: 0},
{label: 'Dev', value: 0}
];
// productDatas = [{date: ..., value: ... , ...}, {date: ..., value: ... , ...}, ... ]
for (const productData in productDatas) {
const month = productData.date.getMonth();
chartDataPoints[month].value += productData.value; // 합계
}
const [isActive, setIsActive] = useState(false);
...
<div style={{color: isActive ? 'red' : 'black'}}></div>
여러분이 해야 할 작업은 제공된 리액트 앱의 <p>Style me</p>
요소에 스타일(color: red
)을 동적으로 적용하는 것입니다.
<button>
이 처음 클릭될 때 스타일은 인라인 스타일(즉, style
속성/prop을 통해) 적용되어야 합니다. 버튼을 다시 클릭하면, 스타일은 초기 스타일인 color: white
로 다시 전환되어야 합니다.
버튼이 이 두 스타일 사이를 전환하는지 확인합니다(color: white
<=> color: red
).
버튼을 클릭하기 전, 완성된 앱의 모습은 다음과 같습니다:
버튼을 클릭한 후의 모습은 다음과 같습니다:
버튼이 다시 클릭되었을 때의 모습은 다음과 같습니다:
내 코드 (PASS)
import React from 'react';
// don't change the Component name "App"
export default function App() {
const [isToggle, setIsToggle] = React.useState(false);
const handleClick = () => {
setIsToggle(prev => !prev);
}
return (
<div>
<p style={{color: isToggle ? 'red' : 'white'}}>Style me!</p>
<button onClick={handleClick}>Toggle style</button>
</div>
);
}
여러분이 해야 할 작업은 제공된 리액트 앱의 <p>Style me</p>
요소에 CSS 클래스(active
)를 동적으로 적용하는 것입니다. 이 작업은 이전 코딩 연습과 매우 유사하지만, 인라인 스타일이 아닌 CSS 클래스를 동적으로 설정합니다.
버튼을 처음 클릭할 때 스타일은 CSS 클래스로(즉, className
속성/prop을 통해) 적용되어야 합니다. <button>
을 다시 클릭하면 모든 CSS 클래스가 <p>
요소에서 제거되어야 합니다(이 상태도 초기 상태여야 합니다).
버튼이 이 두 가지 스타일 사이를 전환하는지 확인합니다(CSS 클래스 없음 <=> active
CSS 클래스).
버튼을 클릭하기 전의 완성된 앱의 모습은 다음과 같습니다:
버튼을 클릭한 후의 모습은 다음과 같습니다:
버튼을 다시 클릭했을 때의 모습은 다음과 같습니다:
내 코드 (PASS)
import React from 'react';
// don't change the Component name "App"
export default function App() {
const [isActive, setIsActive] = React.useState(false)
const handleClick = () => {
setIsActive(prev => !prev);
}
return (
<div>
<p className={isActive && 'active'}>Style me!</p>
<button onClick={handleClick}>Toggle style</button>
</div>
);
}
const StyledButton = styled.button`
color: ${props => props.active ? 'red' : 'black'}
`
<StyledButton active={isActive}>버튼</StyledButton>
const Button = styled.button`
@media (min-width: 768px) {
width: auto;
}
`;