Okay so I have this large page of code but have simplified the problem below. Basically I am creating a matching app and have this component below named "Match", it gets a list of dicts from the state and I create new lists within the Match component so that I can randomize the definitions and words. The problem I face is that in the return section I want a different styling to be rendered depending on whether the correct word and definitions where pressed. I have gotten the "randomization and check if matching" code to work correctly. The only thing wrong is that after it returns true that both the definition and word match, I can't figure out how to re-render the return so only those two items are rendered with different styling.(in the code below only the definitions will change) Below I added a simple test key when creating a new list, to be the variable that will determine the styling. Look for ---> in the code below to see important notes/code.
I have tried using useEffect and placing randomArr
in the form of useEffect(),[randomArr];
but no luck and also tried using useState but to no luck received error of to many renders. Just need help making sure that when test is updated to not null that the styling changes.
import React, { Fragment } from "react";
import { useSelector } from "react-redux"; //used
import { Grid, Button } from "@mui/material";
const Match = () => {
const items = useSelector((state) => state.posts);
let x = null;
const wordArr = []; //New list created to randomize list taken in from state
const randomArr = []; //same above
const newList = []; //same above
// ##### new list to mix up words and defs #### //
for (let i = 0; i < items.length; i++) {
newList.push(items[i]);
wordArr.push({ _id: items[i]._id, definition: items[i].definition });
}
for (let i = 0; i < items.length; i++) {
let temp2 = wordArr[Math.floor(Math.random() * wordArr.length)]; //gets random obj
randomArr.push({ _id: temp2._id, definition: temp2.definition, test: null }); // ----> adds Null so it renders the first option below
wordArr.splice(wordArr.indexOf(temp2), 1); //deletes random obj so does not get called again
}
// ####### //
const checkId = (id) => {
if (x) {
if (id._id === x) {
console.log("Match");
console.log(id);
console.log(x);
newList.pop();
console.log(newList);
id.test = true // ---->Changes test to something so it returns true below
} else {
console.log("no match");
}
x = null;
} else {
x = id._id;
}
};
return (
<div>
<Grid container spacing={2}>
{items.map((item, i) => (
<Fragment key={`word${item._id}`}>
<Grid item xs={6}>
<Button fullWidth onClick={() => checkId(item)}>
<SimpleCard item={item.word}></SimpleCard>
</Button>
</Grid>
{randomArr[i].test ? (
<Grid item xs={6}>
<div> Changed</div>
</Grid>
) : (
<Grid item xs={6}>
<Button fullWidth onClick={() => checkId(randomArr[i])}>
<SimpleCard item={randomArr[i].definition}></SimpleCard>
</Button>
</Grid>
)}
</Fragment>
))}
</Grid>
</div>
);
};
export default Match;
Edit changing the checkId to use state
const [x, setX] = useState(null);
const [x, setX] = useState(null);
const checkId = (id) => {
if (x) {
if (id._ID === x) {
console.log("Match");
console.log(id._id);
console.log(x);
newList.pop();
console.log(newList);
id.test = true
} else {
console.log("no match");
}
setX(null);
console.log("reset");
} else {
setX(id._id);
console.log("set X");
}
};
[MostUpdated] Error Code
const randomfunc = () => {
for (let i = 0; i < items.length; i++) {
newList.push(items[i]);
wordArr.push({ _id: items[i]._id, definition: items[i].definition });
}
for (let i = 0; i < items.length; i++) {
let temp2 = wordArr[Math.floor(Math.random() * wordArr.length)]; //gets random obj
randomArr.push({
_id: temp2._id,
definition: temp2.definition,
test: null,
}); // ----> adds Null so it renders the first option below
wordArr.splice(wordArr.indexOf(temp2), 1); //deletes random obj so does not get called again
}
};
const [x, setX] = useState(null);
useEffect(() => {
randomfunc();
console.log("test");
});