问题描述
我正在开发React应用。单击按钮时,功能可以启动特定卡的计算。但是问题是,CharacterDetails.js模块中的countCounts函数在开始时就将所有20个位置加1,我通过在发送前先确定条件解决了这个问题,但是这种解决方案可以算第一次点击。
在Character.js模块变量中,combinedViews在LOG中给我带来了摆姿势的结果,但是当我尝试将其作为参数传递给另一个函数时,它给我的结果就像一步被单击之前一样。
我不知道是因为我在sumObjectByKey中减少methon还是在reducer中因为某些原因而减少了派遣状态,但是我想要达到的聘用却是对自第一次点击以来的每次点击计数……
Character.js(主模块)
import React,{ useState,useEffect } from "react";
import { Link } from "react-router-dom";
import CharacterDetails from "./CharacterDetails";
import Search from "../ui/Search";
import GetCardStats from "../tools/getCardStats";
import { useSelector} from 'react-redux';
import HandleTest from '../tools/HandleTest'
const Characters = ({ isLoading }) => {
const [items,setItems] = useState([]);
const [query,setQuery] = useState("");
const [views,setViews] = useState({});
const [views2,setViews2] = useState([]);
const localURLs = "http://localhost:3010/cardStats";
const URLs = [`https://rickandmortyapi.com/api/character/?name=${query}`];
const viewedState = useSelector(state => state.countView)
const viewed = viewedState.count
//////////// [] z kliknietym parametrem
let viewCounterResults = HandleTest(viewed);
// const viewCounterResults = lastClickedElementDouble()
console.log(viewCounterResults);
console.log('views',views);
}
function sumObjectsByKey (...objs) {
const x = objs.reduce((a,b) => {
console.log('>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<');
let firstRun = true;
for (const k in b) {
if (b.hasOwnProperty(k)) {
if(firstRun) {
a[k] = (a[k] || 0) + b[k]
firstRun = false;
} else {
a[k] = (a[k] || 0) + b[k]
}
}
}
return a
},{})
// console.log(x);
return x
}
let combinedViews = sumObjectsByKey(views,viewCounterResults);
console.log("sumObjectsByKey -> viewCounterResults",viewCounterResults)
console.log("combinedViews",combinedViews)
const title = Object.keys(combinedViews)
const description = Object.values(combinedViews)
console.log("DESCRiption",description)
// DESCRIPTION OK
//---------------------------------------------------------------
let sendPost = (titleSend,descriptionSend)=>{
setViews2(combinedViews)
console.log(views2);
console.log(combinedViews);
fetchGo(titleSend,descriptionSend )
}
const fetchGo = (title,description) => {
const viewedUP = viewedState.count
console.log("viewedUP",viewedState)
console.log('%cDESCRIPTION in Fetch()','background: #222; color: #dd3a11',description);
console.log('%cTITLE in Fetch()',title);
fetch ('http://localhost:3010/cardStats',{
method: 'POST',headers: {
'Content-Type': 'application/json'
},body: JSON.stringify({
title: title,description: description
})
})
.then(res => {
return res.json()
})
.catch( error => console.log(error))
}
///////////////////// FETCH CARDS FROM API
useEffect(() => {
const fetchItems = async () => {
console.time("⏱");
for (const url of URLs) {
const res = await fetch(url);
const items = await res.json();
setItems(items.results);
}
console.timeEnd("⏱");
};
fetchItems();
const cardViews = async () => {
///Fetchowanie
const data = await GetCardStats(localURLs);
let keys = data[0].title ;
let values = data[0].description ;
//// Merge 2 Arrays => Object
const cardViewsState = {};
keys.forEach((key,i) => cardViewsState[key] = values[i]);
console.log(cardViewsState);
setViews(cardViewsState);
}
cardViews();
},[query]);
return isLoading ? (
<h1>Loading...</h1>
) : (
<div className="container">
<Search getQuery={(q) => setQuery(q)} />
<section className="cards">
{
// check items isn't null/undefined before rendering ( items && items.map())
items &&
items.map((item) => (
<CharacterDetails
key={item.id}
item={item}
views={combinedViews}
// views={views}
viewReqDB= { (views) =>{ sendPost(title,description) }}
// viewReqDB= { () =>{ sendPost(title,description) }}
></CharacterDetails>
))
}
</section>
</div>
);
};
export default Characters;
CharacterDetails.js
import React,useEffect } from "react";
import { Link } from "react-router-dom";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActionArea from "@material-ui/core/CardActionArea";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import CardMedia from "@material-ui/core/CardMedia";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import IconButton from "@material-ui/core/IconButton";
import FavoriteIcon from "@material-ui/icons/Favorite";
import VisibilityIcon from "@material-ui/icons/Visibility";
import StarBorderTwoToneIcon from "@material-ui/icons/StarBorderTwoTone";
import { useSelector,useDispatch } from "react-redux";
import { increment } from "../../actions";
const CharacterDetails = ({ item,views,viewReqDB }) => {
const [isFavourite,setIsFavourite] = useState(0);
let [isViewed,setIsViewed] = useState(0);
useEffect(() => {
isFavourite % 2
? dispatch({ type: "ADDFAV",favID: `${item.id}` })
: dispatch({ type: "RMVFAV",favID: `${item.id}` });
},[isFavourite]);
useEffect(() => {
isViewed > 0
?
dispatch({ type: "VIEWED",count: isViewed,id: `${item.id}` })
// : console.log('')
: dispatch({ type: "VIEWED",id: `${item.id}` })
},[isViewed]);
const favourite = useSelector((state) => state.isFavouriteRedurec);
const dispatch = useDispatch();
const classes = useStyles();
// console.log(item);
// console.log(views);
// Take views for display Accual State Views
const countViews = () => {
for (const [key,value] of Object.entries(views)) {
if(`${item.id}` === key) {
console.log(value)
return value
}
}
}
return (
<Card className={`${classes.root} flip-in-ver-right`}>
<Link to={`/characterspecification/${item.id}`}>
<div>
<CardActionArea>
<CardMedia
className={classes.media}
image={item.image}
alt={item.name}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{item.name}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{item.species}
{item.status}
</Typography>
</CardContent>
</CardActionArea>
</div>
</Link>
<CardActions className={classes.actionPanel}>
<Button
className={classes.actionPanel}
onClick={() => dispatch(increment())}
size="large"
color="primary"
>
{ countViews()}
+
{/* {views} */}
</Button>
<IconButton
aria-label="add to favorites"
className={classes.actionPanel}
onClick={() => setIsFavourite(isFavourite + 1)}
>
<VisibilityIcon /> {favourite.favIDs}
</IconButton>
<Button size="small" color="primary">
<StarBorderTwoToneIcon
className={classes.clicked}
onClick={() => {setIsViewed(isViewed +1); viewReqDB(views);}}
// onClick={() => {setIsViewed(isViewed +1); callB(item); viewReqDB()}}
/>
</Button>
</CardActions>
</Card>
);
};
export default CharacterDetails;
这是React正在派遣的reducer之一 countViews.js
const initialViewState = {
listName: 'Vievd',count: [],}
const countViews = (state = initialViewState,action) => {
switch (action.type) {
case 'VIEWED':
return{ ...state,count:[...state.count,action.id]}
case 'NOTVIEWED':
return{...state,action.id ]}
default:
return state
}
}
export default countViews;
还有将数组组合成对象的函数 HandleTest.js
import React from 'react'
const HandleReducer = ( arr ) => {
// Counting values in array f.g([1,1,3,4,] expect a:[1,4] b:[3times,1time,2times])
function countView(arr) {
let a = [],b = [],prev;
arr.sort();
for ( let i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
return [a,b];
}
let result = countView(arr)
// Merge arrays as a key/value
const mergeArrays = (arr1,arr2) => {
let l = Math.min(arr1.length,arr2.length),ret = []
for(let i=0; i<l; i++) {
// ret.push(`Card no. ${arr1[i]} was clicked ${arr2[i]} times`);
}
let keys = arr1;
let values = arr2
let firstRun = true;
let result = {};
// keys.forEach((key,i) => result[key] = values[i] );
keys.forEach((key,i) => result[key] = values[i] );
console.log(result);
return result;
}
const countedViews = mergeArrays(...result)
return countedViews
}
export default HandleReducer
我已经为此战斗了很长时间,但老实说,我不知道如何解决这个问题……。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)