A bit of a mouthful question...
I've looked over dozen of similar questions, but they either have to do with components in the same file, or with singular buttons.
Desired Effect:
I'm trying to display repository commits once a user clicks on a card of a specific repo. The commits are hidden until they press a button. If the user clicks the button when the commits are showing, it should hide the commits. Continuous clicking of a repo card should show/hide/show/hide/etc. the appropriate commit cards.
function Home() {
const title = "Projects"
const message = "Projects fetched from Github using their GQL API."
const [clicked, setClicked] = useState(false)
const [repoInfo, setRepoInfo] = useState({ name: "Website", owner: "FernandoH-G" })
return (
<Container>
<Jumbo title={title} message={message} />
<CardDeck>
<RepoCards clicked={clicked} setClicked={setClicked} setRepoInfo={setRepoInfo} />
</CardDeck>
<br/>
<CardDeck>
{clicked && <CommitCards repoInfo={repoInfo} />}
</CardDeck>
</Container>
);
}
function RepoCards(props) {
const { loading, error, data } = useQuery(GET_PINNED_REPOS);
const [radioValue, setRadioValue] = useState("");
if (loading) return (
<Loading
message="Fetching pinned repositories..."
color="secondary" />
)
if (error) return (
<Loading
message="Error fetching pinned repositories."
color="danger" />
)
const pinEdges = data.user.pinnedItems.edges
return (
pinEdges.map((pin, idx) => (
<Card
key={pin.node.name}
className="text-center"
border="light">
<Card.Body>
<Card.Header as="h5"> {pin.node.name}</Card.Header>
<Card.Link href={pin.node.url}>
<Card.Img variant="top" src={chooseIMG(pin.node.name)} />
</Card.Link>
<Card.Text> {pin.node.description}</Card.Text>
</Card.Body>
<ButtonGroup toggle>
<ToggleButton
key={pin.node.name}
type="radio"
variant="outline-secondary"
name="Button Radio"
value={pin.node.name}
checked={radioValue === pin.node.name}
onChange={(e) => setRadioValue(e.currentTarget.value)}
onClick={() => {
console.log(`${idx} card clicked. click value: ${props.clicked}`)
props.setRepoInfo(
{
name: pin.node.name,
owner: pin.node.owner.login
})
props.setClicked(!clicked) // This should work,right?
// if (radioValue === pin.node.name) {
// // props.setClicked(prevVal => !prevVal)
// props.setClicked(false)
// } else {props.setClicked(true)}
}}>
Last Update:{' '}
{parseDate(pin.node.pushedAt)}
</ToggleButton>
</ButtonGroup>
</Card>
))
)
}
I'm including the CommitCards component code even though I don't think it's necessary.
const CommitCards = (props) => {
const name = props.repoInfo.name
const owner = props.repoInfo.owner
const { loading, error, data } = useQuery(GET_REPO_COMMITS, {
variables: { name, owner },
});
if (loading) return (
<Loading message={`Fetching ${name} commits...`} color="secondary" />
);
if (error) return (
<Loading message={`Error fetching ${name} commits.`} color="danger" />
);
const commits = data.repository.defaultBranchRef.target.history.edges
return commits.map(com => (
<Card
key={com.node.url}
bg={"dark"}
style=
border="info">
<Card.Body>
<Card.Link href={com.node.url}>
Commit Date:{'\n'}
{parseDate(com.node.committedDate)}
</Card.Link>
<Card.Text>
{parseText(com.node.message)}
</Card.Text>
</Card.Body>
</Card>
))
}
After looking at the console, and recording the state of clicked, it may be a rendering issue. I say this because it seems to be rendering everything twice, thus messing with the value of clicked.
I don't know. I've been on this for a few days now. Below is a screenshot of the consoles output after I click each button. Commits fail to even show; not close to having the effect I desire.
Huge development
Following the suggestion of @deckele, I was working on a code sandbox when I noticed that my initial code posted...actually works, sorta. I can definitely optimize the posted code. I wasn't able to get react-bootstrap to work in code sandbox, but that turned out for the better.
It turns out that a <ToggleButton> reads clicking the label, the text portion, as a click on the console, twice. However, you have to hit the very small actual input area. You can check out the label registering as a click in the code sandbox.

Unfortunately, the input area is covered by the label, which is essentially the whole button.
Since this question took a turn, I will be closing up this one, and probably opening up a new react-bootstrap one.
from How to show/hide component in parent component via a button in a child component when using a map of buttons?

No comments:
Post a Comment