function tablemap(data, index) {
console.log("1 screen loading", sortData.isLoaded);
console.log("2 screen data", data);
console.log("3 screen data pedometer", data.pedometer);
}
{sortData.isLoaded
? sortData?.data.map((item, index) => tablemap(item, index))
: null}
It seems really weird.
when I console data it shows the second console result.
if you see the data
dict, it has pedometer 162.
however when I console data.pedometer
at the same time in below line, it prints 0, not 162.
Stack overflow says that it's duplicate with this question:
But my problem is not just about console.
function tablemap(data, index) {
console.log("1 screen loading", sortData.isLoaded);
console.log("2 screen data", data);
console.log("3 screen data pedometer", data.pedometer);
const indexodd = index % 2 == 0;
const birthDate =
data.birthday.slice(0, 2) " / " data.birthday.slice(2, 4);
return (
<tr key={data.id}>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.pedometer}
</td>
</tr>
)}
so in above code, {data.pedometer}
shows 0, not 162.
How can I make this be shown as 162?
According to comments, it seems because data
is reactjs state.
what causes problem in this case?
And how to fix this?
full code
export default function Rank() {
const { register, handleSubmit } = useForm();
const [startDate, setStartDate] = useState(
new Date(new Date().getFullYear(), new Date().getMonth(), 1)
);
const [endDate, setEndDate] = useState(new Date());
const { data: userData } = useQuery(SEE_ALL_USERS_QUERY);
const { data: feedData } = useQuery(SEE_ADMIN_FEED);
const { data: poemData } = useQuery(SEE_ADMIN_POEM);
const { data: fpLikesData } = useQuery(SEE_ADMIN_FPLIKES);
const { data: fpCommentsData } = useQuery(SEE_ADMIN_FPCOMMENTS);
const { data: pedometerData } = useQuery(SEE_ADMIN_PEDOMETERS);
const [initialuser, setInitialuser] = useState([]);
const [datasum, setDatasum] = useState([]);
let datasumArray = [];
const [perioddata, setPerioddata] = useState([]);
const [resultData, setResultData] = useState([]);
const [sortData, setSortData] = useState([]);
const [criteria, setCriteria] = useState("점수");
const loading = useRef(false);
const [searchinput, setSearchinput] = useState("");
const [csvdata, setCsvdata] = useState([[]]);
// 1. userData point~pedometer 추가
function userDataFormat(userData) {
return userData.map((element) => ({
...element,
point: 0,
feed: 0,
poem: 0,
like: 0,
comment: 0,
pedometer: 0,
}));
}
// 2. 점수 및 각 영역별 카운트 (new)
function resultDateFunc(perioddata) {
let updateInitialuser = initialuser;
for (let i = 0; i < perioddata.length; i) {
let certainUserIndex = updateInitialuser.findIndex(
(element) => element.id === perioddata[i].user.id
);
if (perioddata[i].__typename === "Feed") {
updateInitialuser[certainUserIndex].point = 10;
updateInitialuser[certainUserIndex].feed;
} else if (perioddata[i].__typename === "Poem") {
updateInitialuser[certainUserIndex].point = 10;
updateInitialuser[certainUserIndex].poem;
} else if (perioddata[i].__typename === "Comment") {
updateInitialuser[certainUserIndex].point = 2;
updateInitialuser[certainUserIndex].comment;
} else if (perioddata[i].__typename === "Like") {
updateInitialuser[certainUserIndex].point = 1;
updateInitialuser[certainUserIndex].like;
} else if (perioddata[i].__typename === "Pedometer") {
updateInitialuser[certainUserIndex].point = Math.floor(
perioddata[i].stepCount / 1000
);
updateInitialuser[certainUserIndex].pedometer =
perioddata[i].stepCount;
}
}
return updateInitialuser;
}
// 3. 정렬
function criteriaSortFunc(resultData) {
if (criteria === "점수") {
let pointSort = resultData.sort(function (a, b) {
return b.point - a.point;
});
return pointSort;
} else if (criteria === "일상") {
let feedSort = resultData.sort(function (a, b) {
return b.feed - a.feed;
});
return feedSort;
} else if (criteria === "시") {
let poemSort = resultData.sort(function (a, b) {
return b.poem - a.poem;
});
return poemSort;
} else if (criteria === "댓글") {
let commentSort = resultData.sort(function (a, b) {
return b.comment - a.comment;
});
return commentSort;
} else if (criteria === "좋아요") {
let likeSort = resultData.sort(function (a, b) {
return b.like - a.like;
});
return likeSort;
} else if (criteria === "걸음수") {
let pedometerSort = resultData.sort(function (a, b) {
return b.pedometer - a.pedometer;
});
return pedometerSort;
}
}
useEffect(() => {
if (userData !== null && userData !== undefined) {
loading.current = false;
setInitialuser(userDataFormat(userData?.seeAllUsers));
}
}, [userData, startDate, endDate]);
useEffect(() => {
datasumArray = [];
if (
feedData !== undefined &&
feedData !== null &&
poemData !== undefined &&
poemData !== null &&
fpLikesData !== undefined &&
(fpLikesData !== null) & (fpCommentsData !== undefined) &&
fpCommentsData !== null &&
pedometerData !== undefined &&
pedometerData !== null
) {
datasumArray.push(
...feedData.seeAdminAllFeeds,
...poemData.seeAdminAllPoems,
...fpLikesData.seeAdminAllLikes,
...fpCommentsData.seeAdminAllComments,
...pedometerData.seeAdminAllPedometers
);
setDatasum(datasumArray);
}
}, [feedData, poemData, fpLikesData, fpCommentsData, pedometerData]);
useEffect(() => {
const periodDatasum = datasum.filter(
(element) =>
parseInt(element.createdAt) >= startDate.getTime(0, 0, 0, 0) &&
parseInt(element.createdAt) <= endDate.getTime(23, 59, 59, 999)
);
setPerioddata(periodDatasum);
}, [datasum, startDate, endDate]);
useEffect(() => {
if (
perioddata !== undefined &&
perioddata !== null &&
initialuser.length !== 0
) {
setResultData(resultDateFunc(perioddata));
}
}, [perioddata, initialuser]);
useEffect(() => {
if (resultData !== undefined && resultData !== null) {
setSortData(criteriaSortFunc(resultData));
}
}, [resultData]);
useEffect(() => {
console.log("sortData Length", sortData.length);
if (sortData.length !== 0) {
loading.current = true;
console.log("sortdata set", sortData);
}
}, [sortData]);
useEffect(() => {
if (sortData.length !== 0) {
setCsvdata(
[
[
"순위",
"이름",
"나이",
"출생년도",
"생일",
"성별",
"핸드폰 번호",
"거주 지역",
"소속 기관",
"점수",
"일상",
"시",
"댓글",
"좋아요",
"걸음수",
],
].concat(sortData.map((item) => csvmap(item)))
);
}
}, [sortData]);
function tablemap(data, index) {
console.log(loading);
console.log("pedometer", data.pedometer);
let newdataset = JSON.parse(JSON.stringify(data));
console.log("string pedometer", newdataset.pedometer);
const indexodd = index % 2 == 0;
const birthDate =
data.birthday.slice(0, 2) " / " data.birthday.slice(2, 4);
return (
<tr key={data.id}>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{index 1}위
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.name}
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.age}
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.birthyear}
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{birthDate}
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.gender}
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.cellphone}
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.region}
</td>
<td
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-left text-sm`}
>
{data.community.communityName}
</td>
<th
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-center text-sm`}
>
{data?.point}
</th>
<th
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-center text-sm`}
>
{data?.feed}
</th>
<th
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-center text-sm`}
>
{data?.poem}
</th>
<th
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-center text-sm`}
>
{data?.comment}
</th>
<th
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-center text-sm`}
>
{data?.like}
</th>
<th
className={`${
indexodd ? "bg-gray-100" : "bg-white"
} border-b-1 border-slate-300 justify-center items-center px-2 py-1 text-center text-sm`}
>
{data?.pedometer}
</th>
</tr>
);
}
const onValid = (input) => {
const searchresult = [];
for (let i = 0; i < sortData.length; i ) {
if (sortData[i].name === input.searchname) {
searchresult.push(sortData[i]);
}
}
setSortData((olddict) => {
return {
isLoaded: true,
data: searchresult,
};
});
};
return (
<Layout click="순위 정보">
<div className="w-full flex flex-row items-start mb-10 justify-between">
<div className="w-1/2 flex flex-col">
<div className="w-60 flex flex-row">
<DatePicker
selected={startDate}
onChange={(date) => setStartDate(date)}
className="border border-gray-500 bg-gray-50 text-black py-1 rounded-md font-bold text-center mr-3"
/>
<span className="text-gray-500 font-bold text-lg"> - </span>
<DatePicker
selected={endDate}
onChange={(date) => setEndDate(date)}
className="border border-gray-500 bg-gray-50 text-black py-1 rounded-md font-bold text-center ml-3"
/>
</div>
<div className="h-5"></div>
<div className="flex flex-row items-start">
<span className="mr-5 font-bold">정렬 기준 설정</span>
<select
value={criteria}
onChange={(event) => setCriteria(event.target.value)}
className="border border-gray-600 border-collapse text-black py-1 w-32 border-noneoutline-none rounded-md text-center"
>
<option name="point" className="text-gray-600">
점수
</option>
<option name="feed" className="text-gray-600">
일상
</option>
<option name="poem" className="text-gray-600">
시
</option>
<option name="like" className="text-gray-600">
좋아요
</option>
<option name="comment" className="text-gray-600">
댓글
</option>
<option name="comment" className="text-gray-600">
걸음수
</option>
</select>
</div>
</div>
<form onSubmit={handleSubmit(onValid)}>
<input
{...register("searchname", {
required: "이름을 적어주세요.",
onChange: (text) => {
setSearchinput(text);
},
})}
type="text"
placeholder="이름을 검색해주세요."
className="focus:outline-none focus:border-[#FF2D78] border-2 w-56 border-gray-500 rounded-md py-1 text-center"
></input>
<button className="bg-gray-300 rounded-md py-1 px-3 ml-2">
검색
</button>
</form>
<div>
<CSVLink
data={csvdata}
className="bg-gray-500 rounded-md py-2 px-5 text-white font-bold"
>
CSV 다운로드
</CSVLink>
</div>
</div>
<table className="border-collapse">
<tbody>
<tr>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
순위
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-2 text-left text-sm">
이름
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
나이
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
출생년도
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
생일
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
성별
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
핸드폰 번호
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
거주 지역
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-left text-sm">
소속 기관
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-center text-sm">
점수
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-center text-sm">
일상
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-center text-sm">
시
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-center text-sm">
댓글
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-center text-sm">
좋아요
</th>
<th className="border-b-2 border-slate-700 justify-center items-center px-2 py-1 text-center text-sm">
걸음수
</th>
</tr>
{loading
? sortData.map((item, index) => tablemap(item, index))
: null}
</tbody>
</table>
</Layout>
);
}
CodePudding user response:
So, for a moment I will ignore the fact that your using these values in React, and focus exclusively on the first information you provide, which is that a logged object has different property values when inspected through the console.
In a synchronous logging envirnoment such as Node.js the behaviour is pretty straightforward:
const someObject = { someProperty: 23 };
console.log(someObject);
// Logs: { someProperty: 23 }
console.log(someObject.someProperty);
// Logs: 23
And in no way the logged object and the logged property value will have different values. This is because when logging an object the standard library of Node.js has to cycle through all properties of the object, extract the values, and then putting them on screen.
In the example code there’s nothing that can happen to someObject
(and specifically to someProperty
) between the two console.log
calls.
But the browser’s console is not synchronous. When you log an object its properties are “lazily shown”, that means that properties are evaluated only once you expand the object in the interactive console, and not before.
That mean that there’s plenty of time for things to go wrong:
const someObject = { someProperty: 23 };
console.log(someObject);
console.log(someObject.someProperty);
setTimeout(() => { someObject.someProperty = 42; }, 0);
The browser may show the correct property values in the object, but once you expand it to show all properties (such as the inherited ones) you will no longer see 23
but 42
.
That said, your code is mutating the object referenced by data
.
This is a big “no no” in React land for values that must become part of the state of your component.
Your code is quite lengthy so I’m not sure i catched the culprit, but looks like your problem lies in resultDateFunc
where you are mutating updateInitialuser
thinking it will not mutate initialuser
, but in fact it does.
This is because you are not creating a new object, but rather giving that same object a new “name”.
You used the correct trick somewhere else, that is to JSON serialize and deserialize the value before mutating it.
const updateInitialuser = JSON.parse(JSON.stringify(initialuser));
I don’t think that this is the correct approach to be honest though. It would be better to create a completely new object with the computations results you expect.
One last point: you are creating a lot of states… for nothing.
Your pattern is the following:
const someValue = useQuery(something);
const [computedValue, setComputedValue] = useState(null);
useEffect(() => {
setComputedValue(doSomethingWith(someValue));
}, [someValue]);
This is so unnecessary! Please use the useMemo
hook to store heavy computations’ results!
const someValue = useQuery(something);
const computedValue = useMemo(() => {
return doSomethingWith(someValue);
}, [someValue]);
Please the relevant part of the new (Beta) React.js documentation.