Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context not accessible inside Stage #281

Closed
Ultre00 opened this issue Feb 28, 2021 · 4 comments
Closed

Context not accessible inside Stage #281

Ultre00 opened this issue Feb 28, 2021 · 4 comments

Comments

@Ultre00
Copy link

Ultre00 commented Feb 28, 2021

I am trying to access a context where my game data will be stored. However this context is not accessible from children wrapped inside the Stage Component.

Setup:

interface GameState {
  pieces: number[],
  selected?: number
}

interface IGameManager {
  selectPiece: (piece: number) => void,
  gameState: GameState
}

const GameContext = React.createContext<IGameManager | undefined>(undefined);

const GameManager: FunctionComponent = props => {

  const [state, setState] = useState<GameState>({
    pieces: [
      1, 2, 3
    ],
    selected: 1,
  })

  const selectPiece = (piece: number) => {

  }

  return (
    <GameContext.Provider value={{ selectPiece: selectPiece, gameState: state }} {...props} />
  )
}

const Test: FunctionComponent = props => {
  const context = useContext(GameContext);
  console.log(context);
  return <div />
}

Console log works fine here:

function App() {
  return (
    <div>
      <GameManager>        
          <Test />
      </GameManager>
    </div>
  );
}

But this doesn't work:

function App() {
  return (
    <div>
      <GameManager>
        <Stage>
          <Test />
        </Stage>
      </GameManager>
    </div>
  );
}

Also I have never used PixiJS before and this is a first of using React in combination with TypeScript. If it is not possible to store game data with a context, is there a preffered way?

Additional info

  • @inlet/react-pixi version: 6.1.1
  • React version: 17.0.1
  • ReactDOM version: 17.0.1
  • PIXI version: 5.3.8
@inlet
Copy link
Collaborator

inlet commented Mar 1, 2021

Duplicate #77

Unfortunately customer reconcilers cannot access its parent Context. This is a well known React issue, however you can bypass this with a simple Context Bridge component like this:

// context-bridge
const ContextBridge = ({ children, Context, render }) => {
  return (
    <Context.Consumer>
      {(value) => render(<Context.Provider value={value}>{children}</Context.Provider>)}
    </Context.Consumer>
  );
};

// stage
import { Stage as PixiStage } from '@inlet/react-pixi';

const Stage = ({ children, ...props }) => {
  return (
    <ContextBridge
        Context={RecoilContext}
        render={(children) => <PixiStage {...props}>{children}</PixiStage>}
    >
      {children}
    </ContextBridge>
  );
};

@inlet inlet closed this as completed Mar 1, 2021
@qpwo
Copy link

qpwo commented Oct 2, 2021

Now that is a useful trick

@qpwo
Copy link

qpwo commented Oct 2, 2021

Typescript version for future readers

export default function ContextBridge<T>(props: {
    children: React.ReactNode
    Context: React.Context<T>
    render: (children: React.ReactNode) => JSX.Element
}): JSX.Element {
    const Context = props.Context
    const result = <Context.Consumer>
        {(value) => props.render(<Context.Provider value={value}>{props.children}</Context.Provider>)}
    </Context.Consumer>
    return result
}

@qpwo
Copy link

qpwo commented Oct 2, 2021

If you try to make to have a prop Parent: React.FC<{ children: React.ReactNode }> then your likely to have an unfixable runtime react error in development mode where it can't verify children is valid children. See here: https://stackoverflow.com/questions/49274143/react-typescript-hoc-passing-component-as-the-prop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants