pixijs / pixi-react

Write PIXI apps using React declarative style
https://pixijs.io/pixi-react/
MIT License
2.33k stars 177 forks source link

Component re-renders wrong Sprite #326

Closed kevinz917 closed 2 years ago

kevinz917 commented 2 years ago

Description

Hey! I'm currently using react-pixi to power my game and I'm running into issues of the renderer mis-rendering blocks. I have a mobx store that stores the tile type on each coordinate and the React component is re-rendering using mobx, but the library is consistently rendering the tile images wrong. However if I refresh the whole webpage again it's rendered correctly. I was wondering if this has happened before, and any best practices to solve this. Thank you!

React component that's being re-rendered.

`const renderBlocks = (map: MasterMap): ReactElement[] => { const allBlocks: ReactElement[] = [];

// add different blocks to render map.forEach((value: TileType, pos: string) => { const { x, y } = decodePosStr(pos); const scaledPos = { x: Number(x) SCALE, y: Number(y) SCALE };

switch (value.type) {
  case blockIdMapping.FENCE:
    allBlocks.push(<Sprite image={FENCE} x={scaledPos.x} y={scaledPos.y} />);
    break;
  case blockIdMapping.WALL:
    allBlocks.push(<Sprite image={WALL} x={scaledPos.x} y={scaledPos.y} />);
    break;
  case blockIdMapping.TURBO:
    allBlocks.push(
      <AnimatedSprite
        isPlaying
        initialFrame={0}
        animationSpeed={0.08}
        images={BOOST}
        x={scaledPos.x}
        y={scaledPos.y}
      />
    );
    break;
  case blockIdMapping.BLOCK:
    allBlocks.push(
      <AnimatedSprite
        isPlaying
        initialFrame={0}
        animationSpeed={0.08}
        images={BLOCKER}
        x={scaledPos.x}
        y={scaledPos.y}
      />
    );
    break;
  case blockIdMapping.WALL:
    allBlocks.push(<Sprite image={WALL} x={scaledPos.x} y={scaledPos.y} />);
    break;
  case blockIdMapping.TOWER:
    console.log('Tower');
    allBlocks.push(
      <AnimatedSprite
        isPlaying
        initialFrame={0}
        animationSpeed={0.08}
        images={TOWER_GREEN}
        x={scaledPos.x}
        y={scaledPos.y}
      />
    );
    const owner = gameCore.towers.get(pos)?.owner;
    if (owner && controlState.isOwner(owner)) {
      allBlocks.push(
        <Sprite
          image={OWNERSHIP_RING}
          scale={0.5}
          x={scaledPos.x - SCALE * 2}
          y={scaledPos.y - SCALE * 2}
          width={SCALE * 5}
          height={SCALE * 5}
        />
      );
    }
    break;
  default:
    break;
}

}) return allBlocks; }

const Blocks = observer(() => { return <>{renderBlocks(toJS(gameCore.masterMap))}</>; }) export default Blocks;`

Thank you!

inlet commented 2 years ago

Hi @kevinz917,

I’m afraid I won’t be able to help you with this. The complete React reconciliation + each components behavior has been tested thoroughly. We haven’t faced this issue before. I guess there must be something in your code that’s causing this issue..

I’ve tested react-pixi with different state managers, including mobx, and everything works as expected.

Feel free to dive in and isolate the problem. Once you’ve isolated the problem, please share a Codepen or codesandbox link that proves any issues related to this library.

I’ll close this issue now, please let me know if we need to reopen this

Thanks!