-
글쓴이글
-
2021년 3월 15일 21:46 #7190
장호영참가자안녕하세요 이틀간 문제를 해결하지 못해 질문글 올립니다ㅠㅠ react 동적으로 데이터 받기에 문제가 있습니다.
import React, { PureComponent } from 'react';
import {
Label,
LineChart,
Line,
CartesianGrid,
XAxis,
YAxis,
Tooltip,
ReferenceArea,
ResponsiveContainer,
} from 'recharts';const initialData = [
{ name: 1, cost: 4.11, impression: 100 },
{ name: 2, cost: 2.39, impression: 120 },
{ name: 3, cost: 1.37, impression: 150 },
{ name: 4, cost: 1.16, impression: 180 },
{ name: 5, cost: 2.29, impression: 200 },
{ name: 6, cost: 3, impression: 499 },
{ name: 7, cost: 0.53, impression: 50 },
{ name: 8, cost: 2.52, impression: 100 },
{ name: 9, cost: 1.79, impression: 200 },
{ name: 10, cost: 2.94, impression: 222 },
{ name: 11, cost: 4.3, impression: 210 },
{ name: 12, cost: 4.41, impression: 300 },
{ name: 13, cost: 2.1, impression: 50 },
{ name: 14, cost: 8, impression: 190 },
{ name: 15, cost: 0, impression: 300 },
{ name: 16, cost: 9, impression: 400 },
{ name: 17, cost: 3, impression: 200 },
{ name: 18, cost: 2, impression: 50 },
{ name: 19, cost: 3, impression: 100 },
{ name: 20, cost: 7, impression: 100 },
];
다음처럼 initialData가 import바로 아래에 위치해있는데요,
동적으로 데이터를 받고싶습니다. 예를들자면
1. axios로 db에서 데이터를 가져오거나
2. 다른 컴포넌트에서 props로 데이터를 가져오거나..
axios를 시도하고싶으나, 무조건 저 위치에서 변수를 동적으로 받아와야해서 함수밖 axios는 불가하더라구요ㅠㅠ
방법이없을까요?
2021년 3월 16일 10:06 #7198
codingapple키 마스터useEffect 바깥에서 ajax요청을 해야하는 특별한 이유가 있나요?
저거 리액트 컴포넌트파일 같은데 useEffect 안에서의 axios로 다 처리할 수 있을 듯 합니다
2021년 3월 16일 14:53 #7226
장호영참가자사실 제가 그래프를 그리고자 하는데 드래그로 줌기능이 되는 차트 라이브러리를 사용하고자 합니다. (rechart)
그런데 보니깐 class문법이라서 제가 코딩애플에서 배운건 function 문법이다 보니.. 좀 어렵더라구요
그래서 젤 상위에 있는 initialData만 바꾸면 제가 원하는 차트가 그려지지 않을까 해서 가독성을 위해 위쪽 코드만 이렇게 올렸습니당..
사실 전체 코드는 이렇습니다.
import React from "react"; import { Label, LineChart, Line, CartesianGrid, XAxis, YAxis, Tooltip, ReferenceArea } from "recharts"; const data = [ { name: 1, cost: 4.11, impression: 100 }, .....//생략 ]; const getAxisYDomain = (from, to, ref, offset) => { const refData = data.slice(from - 1, to); let [bottom, top] = [refData[0][ref], refData[0][ref]]; refData.forEach(d => { if (d[ref] > top) top = d[ref]; if (d[ref] < bottom) bottom = d[ref]; }); return [(bottom | 0) - offset, (top | 0) + offset]; }; const initialState = { data, left: "dataMin", right: "dataMax", refAreaLeft: "", refAreaRight: "", top: "dataMax+1", bottom: "dataMin-1", top2: "dataMax+20", bottom2: "dataMin-20", animation: true }; <strong>export default class StreamingDemo extends React.Component</strong> { constructor(props) { super(props); this.state = initialState; } zoom() { let { refAreaLeft, refAreaRight, data } = this.state; if (refAreaLeft === refAreaRight || refAreaRight === "") { this.setState(() => ({ refAreaLeft: "", refAreaRight: "" })); return; } // xAxis domain if (refAreaLeft > refAreaRight) [refAreaLeft, refAreaRight] = [refAreaRight, refAreaLeft]; // yAxis domain const [bottom, top] = getAxisYDomain(refAreaLeft, refAreaRight, "cost", 1); const [bottom2, top2] = getAxisYDomain( refAreaLeft, refAreaRight, "impression", 50 ); this.setState(() => ({ refAreaLeft: "", refAreaRight: "", data: data.slice(), left: refAreaLeft, right: refAreaRight, bottom, top, bottom2, top2 })); } zoomOut() { this.setState(({ data }) => ({ data: data.slice(), refAreaLeft: "", refAreaRight: "", left: "dataMin", right: "dataMax", top: "dataMax+1", top2: "dataMax+50", bottom: "dataMin" })); } render() { const { data, left, right, refAreaLeft, refAreaRight, top, bottom, top2, bottom2 } = this.state; return ( <div className="highlight-bar-charts"> <button className="btn update" onClick={this.zoomOut.bind(this)}> Zoom Out </button> <p>Highlight / Zoom - able Line Chart</p> <LineChart width={800} height={400} data={data} onMouseDown={e => this.setState({ refAreaLeft: e.activeLabel })} onMouseMove={e => this.state.refAreaLeft && this.setState({ refAreaRight: e.activeLabel }) } onMouseUp={this.zoom.bind(this)} > <CartesianGrid strokeDasharray="3 3" /> <XAxis allowDataOverflow={true} dataKey="name" domain={[left, right]} type="number" /> <YAxis allowDataOverflow={true} domain={[bottom, top]} type="number" yAxisId="1" /> <YAxis orientation="right" allowDataOverflow={true} domain={[bottom2, top2]} type="number" yAxisId="2" /> <Tooltip /> <Line yAxisId="1" type="natural" dataKey="cost" stroke="#8884d8" animationDuration={300} /> <Line yAxisId="2" type="natural" dataKey="impression" stroke="#82ca9d" animationDuration={300} /> {refAreaLeft && refAreaRight ? ( <ReferenceArea yAxisId="1" x1={refAreaLeft} x2={refAreaRight} strokeOpacity={0.3} /> ) : null} </LineChart> </div> ); } }
그래서 만약 제가 initialData를 클래스 안으로 가지고 들어오게되면
const getAxisYDomain 함수랑 const initialState도 안으로 가지고 들어와야할 것 같은데
그러면 복잡해지지 않을까해서 질문드린거였습니다..
할 수 있다면 클래스 안에서 하는게 저도 더 좋은것 같스빈다. (window로 전역변수 쓰는게 너무 안 좋은 아이디어인것 같습니다.)
2021년 3월 16일 16:06 #7228
codingapple키 마스터class로 컴포넌트 만드시면 componentDidMount() 함수 안에서 보통 ajax요청으로 데이터가져와서 state에 반영하거나 합니다
class 바깥에서 함수 만드셔도 class 안에서 가져다쓸 수 있습니다 하지만 setState나 state를 필요로 하는 함수라면 class안에 만드는게 좋은 관습인듯요
class 컴포넌트를 만드는 이유 중 하나가 그 컴포넌트와 관련된 변수, 자료, 함수 메소드를 한번에 보관할 수 있고 외부로부터 보호할 수 있어서입니다
하지만 코드가 더럽다면 데이터 조작하는 것들은 다 리덕스 리듀서로 만들어둬서 그 파일을 더럽히는건 어떨까요
2021년 3월 17일 15:13 #7245
장호영참가자export default class Example extends PureComponent {
constructor(props) {
super(props);
const initialData = this.props.chartdata;
const initialState = {
data: this.initialData,
left: 'dataMin',
right: 'dataMax',
refAreaLeft: '',
refAreaRight: '',
top: 'dataMax+1',
bottom: 'dataMin-1',
top2: 'dataMax+20',
bottom2: 'dataMin-20',
animation: true,
};this.state = initialState;
}
....말씀하신대로 변수를 class안으로 옮겨서, 다음과 같이 코드를 짜서 props로 넘어온 chartdata를 사용하고자하는데요
console.log(this.props.chartdata)하면 배열 원소들이 깔끔하게 찍힙니다.
그런데 위 코드처럼 작성했을 경우
console로 initialState랑 initialData를 찍으면 undefined가 뜹니다!
이건 또 어떻게 해야할까요;;
2021년 3월 17일 16:13 #7252
codingapple키 마스터콘솔창말고 html 내부에 {} 꽂아넣어보도록 합시다 그래도 잘 나오나요
그리고 props는 하위컴포넌트에서 부모가 전해준 내용을 그대로 사용하는게 좋습니다
그래서 부모에게 받은 props랑 하위컴포넌트의 state를 섞는건 약간 위험해보이긴 합니다
-
글쓴이글
- 답변은 로그인 후 가능합니다.