React AJAX
로직과 데이터의 구별을 위한 React AJAX
실행 기능
function AJAX
import React, { useState, useEffect } from 'react';
const Nav = (props) => {
const listTag = props.list.map((arr) => (
<li key={arr.id}>
<a
href={arr.id}
data-id={arr.id}
onClick={(e) => {
e.preventDefault();
props.onChangeId(e.target.dataset.id);
}}
>
{arr.title}
</a>
</li>
));
return (
<nav>
<ul>{listTag}</ul>
</nav>
);
};
const Article = props => {
return(
<article>
<h2>{props.title}</h2>
{props.desc}
</article>
)
}
const NowLoading = () => {
return(
<div>Now Loading ...</div>
)
}
const FuncAJAX = () => {
const [contents, setContents] = useState({
item: { title: 'Welcome', desc: 'Hello, React & Ajax' },
isLoading: false,
});
const [list, setList] = useState({
items: [],
isLoading: false,
});
const [nowId, setNowId] = useState()
const onChangeId = (e) => {setNowId(e)}
useEffect(() => {
setList({...list, isLoading:true})
fetch('list.json')
.then((result) => {
return result.json();
})
.then((json) => {
setList({
items: json,
isLoading: false,
});
});
}, []);
console.log(nowId)
useEffect(()=>{
if(nowId){
setContents({...contents, isLoading:true})
fetch(nowId + ".json")
.then((result) => {
return result.json();
})
.then((json) => {
setContents({
item:{
title:json.title,
desc:json.desc
},
isLoading:false
})
})
}
},[nowId])
let ArticleTag = contents.isLoading ? <NowLoading /> : <Article title={contents.item.title} desc={contents.item.desc} />
let listTag = list.isLoading ? <NowLoading /> : <Nav list={list.items} onChangeId={onChangeId} />
return (
<div style={{ margin: 40, border: '1px solid #aaa', padding: 40, paddingTop: 10 }}>
<h1>React AJAX - Hooks</h1>
{listTag}
{ArticleTag}
</div>
);
};
export default FuncAJAX;
Class AJAX
import React, {Component} from 'react';
class Nav extends Component {
render(){
let listTag = [];
this.props.list.map(arr => {
return listTag.push(
<li key={arr.id}>
<a href={arr.id} data-id={arr.id} onClick={function(e){
e.preventDefault();
this.props.onClick(e.target.dataset.id)
}.bind(this)}>
{arr.title}
</a>
</li>
)
})
return(
<nav>
<ul>
{listTag}
</ul>
</nav>
)
}
}
class Article extends Component{
render(){
return(
<article>
<h2>{this.props.title}</h2>
{this.props.desc}
</article>
)}
}
class NowLoading extends Component{
render(){
return <div>Now Loading...</div>
}
}
class App extends Component {
state = {
article:{
item:{title:'Welcome', desc:"Hello, React & Ajax"},
isLoading:false
},
list:{
items:[],
isLoading:false
}
}
componentDidMount() {
let newList = Object.assign({}, this.state.list, {isLoading:true});
this.setState({list:newList})
fetch('list.json')
.then(function(result){
return result.json();
})
.then(function(json){
this.setState({list:{
items:json,
isLoading:false
}});
}.bind(this))
}
render(){
let NavTag = null;
if(this.state.list.isLoading){
NavTag = <NowLoading></NowLoading>
}else {
NavTag = <Nav list={this.state.list.items} onClick={function(id){
//list contents AJAX
let newArticle = Object.assign({}, this.state.article, {isLoading:true})
this.setState({article:newArticle})
fetch(id + ".json")
.then(function(result){
return result.json();
})
.then(function(json){
this.setState({
article:{
item:{
title:json.title,
desc:json.desc
},
isLoading:false
}
})
}.bind(this))
}.bind(this)} />
}
let ArticleTag = null;
if(this.state.article.isLoading){
ArticleTag = <NowLoading></NowLoading>
}else{
ArticleTag = <Article title={this.state.article.item.title} desc={this.state.article.item.desc} />
}
return (
<div style={{margin:40, border:"1px solid #aaa", padding:40,paddingTop:10}}>
<h1>Web</h1>
{NavTag}
{ArticleTag}
</div>
)};
}
export default App;
Class Lifecycle
import React, { Component } from 'react'
var classStyle = 'color:red';
class ClassComp extends React.Component {
state = {
number:this.props.initNumber,
date:(new Date()).toString(),
life:"Render"
}
UNSAFE_componentWillMount(){
console.log('%cclass => UNSAFE_componentWillMount', classStyle)
}
componentDidMount(){
console.log('%cclass => conponentDidMount', classStyle)
}
shouldComponentUpdate(nextProps, nextState){
console.log('%cclass => shouldComponentUpdate', classStyle)
return true
}
UNSAFE_componentWillUpdate(nextProps, nextState){
console.log('%cclass => UNSAFE_componentWillUpdate', classStyle)
}
componentDidUpdate(nextProps, nextState) {
console.log("%cclass => componentDidUpdate", classStyle)
}
conponentWillUnmount(){
console.log("%cclass => componentWillUnmount", classStyle)
this.setState({life:"Update"})
}
render() {
console.log('%cclass => render', classStyle)
return(
<div className="container">
<h2 style={{color:"red"}}>class style Component</h2>
<p>Class Life Cycle : {this.state.life}</p>
<p>Number: {this.state.number}</p>
<p>Time : {this.state.date}</p>
<input type="button" value="random" onClick={function(){
this.setState({number:Math.random()})
}.bind(this)}/>
<input type="button" value="date" onClick={function(){
this.setState({date: (new Date()).toString()})
}.bind(this)}/>
</div>
)
}
}
export default ClassComp;
Function Lifecycle
import React,{useState, useEffect} from 'react';
var funcStyle = 'color:blue'
var funcId = 0;
function FuncComp(props) {
const [number, setNumber] = useState(props.initNumber)
const [_date, setDate] = useState((new Date()).toString())
useEffect(function(){
console.log('%cfunc => useEffect number (componentDidMount)'+(++funcId),funcStyle)
document.title = number;
return function(){ //clean up
console.log('%cfunc => useEffect return (componentWillUnMount)'+(++funcId),funcStyle)
}
}, []);//빈배열 2회만 실행
//side Effect-렌더되는 효과, main Effect-화면이 출력되는 코드
useEffect(function(){
console.log('%cfunc => useEffect number (componentDidMount & componentDidUpdate) A'+(++funcId),funcStyle)
document.title = number;
return function(){ //clean up
console.log('%cfunc => useEffect return (componentDidMount & componentDidUpdate)'+(++funcId),funcStyle)
}
}, [number])
//복수 가능
useEffect(function(){
console.log('%cfunc => useEffect(componentDidMount & componentDidUpdate) B'+(++funcId),funcStyle)
document.title = number + ":" + _date;
})
console.log('%cfunc => render '+(++funcId),funcStyle)
return(
<div className="container">
<h2 style={{color:'blue'}}>Function style component</h2>
<p>Number: {number}</p>
<p>date: {_date}</p>
<input type="button" value="random" onClick={
function(){
setNumber(Math.random());
}
}/>
<input type="button" value="date" onClick={
function(){
setDate((new Date()).toString())
}
}/>
</div>
)
}
export default FuncComp