This is not the first time I've encountered this issue with GraphQL, where I will be able to clearly see that the correct data is being fetched by using console.log
but it will render nothing in the UI. The last time I had this problem, the issue was that the "id" wasn't included for one of the nested objects. In this case, I've ensured that both exist:
topBattles {
id
battlers {
id
}
}
If I recall, I was also able to detect that error by console.logging the error
that gets returned by UseQuery
. In this case, no error is being shown.
In graphiql, I can see that I'm receiving the correct data:
This is all of the code for the React front-end. There's nothing noteworthy, it's calling the same GraphQL query that worked in GraphiQl with the same arguments
function TopBattles() {
const { loading, data, error } = useQuery(GET_TOP_BATTLES, {
variables: { battleCount: 5, dateRange: "Weekly" },
});
React.useEffect(() => {
console.log(data);
console.log(error);
}, [data]);
if (loading) return "Loading...";
return (
<>
{data?.topBattles?.length > 0
? data.topBattles.map((battle) => {
<div>Foo</div>;
})
: "bar"}
</>
);
}
export default TopBattles;
from the console.log above, error
returns undefined.
Console.log.data returns the correct data:
Yet for the code:
return (
<>
{data?.topBattles?.length > 0
? data.topBattles.map((battle) => {
<div>Foo</div>;
})
: "bar"}
</>
);
Nothing at all is being rendered. The word "bar" is not even being rendered, which means that it's recognizing that there is an array of data and the data has a length. If I change the code to data?.topBattles?.length > 3
it will render "bar" because the array only has 2 elements in it.
CodePudding user response:
What you're missing is the explicit return statement in your arrow function [1]:
return (
<>
{data?.topBattles?.length > 0
? data.topBattles.map((battle) => {
return <div>Foo</div>; // <== Should have an explicit return
})
: "bar"}
</>
);
// Implicit return (no {})
()=> <div>Foo</div>
// Explicit return (with {})
()=> { return <div>Foo</div> }
CodePudding user response:
Like Kostas mentioned, you forgot the return statement, however if you're only rendering a single element, I would suggest doing it like:
return (
<>
{data?.topBattles?.length > 0
? data.topBattles.map
(
(battle) =>
<div>Foo</div>
)
: "bar"}
</>
);
If you don't use the curly braces, you don't need return, this can be applied everywhere.