pixi-react
pixi-react copied to clipboard
Bug: Multiple instances of Component with `Texture` via `useAssets`
Current Behavior
When you have two Pixi components with a Sprite / Texture of the same URL, it doesn't show up when Mapped, I believe this is an issue with the underlying Cache.
Expected Behavior
N/A
Steps to Reproduce
N/A
Environment
@pixi/reactversion: v8 Betapixi.jsversion: v8Reactversion: 18.0.0ReactDOMversion: 18.0.0- Browser & Version: Chrome 127
- OS & Version: MacOS 14
Possible Solution
No response
Additional Information
No response
Would you mind adding a code snippet illustrating the issue for clarity?
As an example take the following React Component:
'use client';
import { type FC, useCallback } from 'react';
import { useAssets } from '@pixi/react';
import type { Container, Graphics } from 'pixi.js';
export namespace Character {
export type Props = {
name: string;
config?: {
x?: number;
y?: number;
};
};
}
export const Character: FC<Character.Props> = ({
name,
config = { x: 0, y: 0 },
}) => {
const {
assets: [texture],
isSuccess,
} = useAssets([
{
alias: name,
src: `/${name}.webp`
},
]);
const drawWrapper = useCallback(
(graphics: Graphics) =>
graphics
.roundRect(0, 0, 40, 40, 6)
.fill({ 0x95af94 }),
[],
);
return (
<container
zIndex={2}
x={config.x ?? 0}
y={config.y ?? 0}
scale={1}
cursor='pointer'
eventMode='static'
>
<graphics zIndex={1} draw={drawWrapper} />
{isSuccess && (
<sprite
texture={texture}
width={40}
height={40}
zIndex={2}
anchor={0}
/>
)}
</container>
);
};
When calling this Component with a map rendering multiple "versions" of this with the same name prop doesn't render the Sprite, but just the wrapper
Thank you. Nice find!
I have yet to run into this specifically, as I was loading the asset in the parent component and passing the loaded texture into the child component I mapped over.
I can take a crack at adding a test case to https://github.com/pixijs/pixi-react/blob/beta/test/unit/hooks/useAssets.test.tsx. If you have any spare cycles and can capture the failure, it would greatly help expedite the fix. I can take over the failing PR.
I'm about to go on vacation and will be able to take a look at the end of next week.
Thank you. Nice find!
I have yet to run into this specifically, as I was loading the asset in the parent component and passing the loaded texture into the child component I mapped over.
I can take a crack at adding a test case to https://github.com/pixijs/pixi-react/blob/beta/test/unit/hooks/useAssets.test.tsx. If you have any spare cycles and can capture the failure, it would greatly help expedite the fix. I can take over the failing PR.
I'm about to go on vacation and will be able to take a look at the end of next week.
No issues, so when using the useAssets with this approach, what happens is the "first component" calls the useAssets hook, and renders, but for the "second component" it returns undefined. With some debugging I can see that the Pixi Cache is being set properly, but its being removed on an additional call of useAssets
For repro: https://codesandbox.io/p/sandbox/react-pixi-mapped-sprites-dk4jcn
Thanks for the repro; I will probably have to mock fetch, as my current test and mocks do not appear to fail when I attempt to fail the test. Must mock deeper into the mock abyss.
Waiting on beta 13 🚀
I'm with beta 14 and this issue seems still present.
I looked into the source code and the problem seems happen when allAssetsAreLoaded is true (on 2nd+ load and the asset is already presented in the cache), it does nothing and returns isSuccess false with assets empty.
const [state, setState] = useState<UseAssetsResult<T>>({
assets: Array(assets.length).fill(undefined),
isError: false,
isPending: true,
isSuccess: false,
status: UseAssetsStatus.PENDING,
});
...
const allAssetsAreLoaded = assets.some(assetsLoadedTest<T>);
if (!allAssetsAreLoaded) {
...
}
return state;
Meanwhile, useAsset still works well although it's marked as deprecated:
Doesn't work:
const { assets: [texture], isSuccess } = useAssets(["assets/pipe-green.png"]);
return (isSuccess && <sprite texture={texture} width={10} height={50} />);
Works:
const texture = useAsset("assets/pipe-green.png");
return (<sprite texture={texture} width={10} height={50} />);
@furic The PR that fixes this issue has not been merged yet and is still open https://github.com/pixijs/pixi-react/pull/533
I can confirm this issue is quite blocking for pretty common use-cases. when you unmount any component that use a texture, and add it back later; it just doesn't display anymore
I'll just use the deprecated useAsset in the meantime :)
I'm likely experiencing this issue as well - I'm using React Router v7, and I have an experience that uses useAssets - if I navigate away, and come back to the view that's using useAssets, the assets never load. It seems that PR #533 likely resolves the problem but I'm having trouble building pixi-react with my current setup to test...
:tada: This issue has been resolved in version 8.0.0-beta.16 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:
:tada: This issue has been resolved in version 8.0.0 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket: