我正在尝试将React实现到游戏引擎。我只是创建一个新的引擎实例并作为prop传递给React root。我无法改变引擎。
const engine = new Engine(configurator);
ReactDOM.render(
<App engine={engine}/>,
document.getElementById('root') as HTMLElement
);
App.tsx
export interface ComponentProps {
engine: Engine;
}
class App extends React.Component<ComponentProps> {
render() {
return (
<div className="container-fluid">
<SaveList saves={this.props.engine.savedGames}
newCharacter={this.props.engine.newGame.bind(this.props.engine)}
/>
</div>
);
}
}
问题是,只要引擎属性发生变化,我就无法更新我的组件。让我们假设一个显示已保存游戏的SaveList
组件,我正在传递这样的道具。
<SaveList
saves={this.props.engine.savedGames}
newCharacter={this.props.engine.newGame.bind(this.props.engine)}
/>
saveList.tsx
export interface SaveListProps {
saves: Save[];
newCharacter: () => any;
}
class SaveList extends React.Component<SaveListProps> {
render() {
return (
<ul className="list-group">
{this.props.saves.map((save, i) => {
return <li key={i} className="list-group-item d-flex justify-content-between align-items-center">
{save.characterName}
<span className="badge badge-primary badge-pill">Days: {save.days}</span>
</li>
})}
</ul>
);
}
}
每当我点击新游戏按钮时,我都可以看到该对象实际上正在改变并且新游戏被推入engine.savedGames
。但我无法让SaveList
重新呈现更改。我还可以使用React开发人员工具
我不知道如何处理这种双向绑定问题。如何使用React连接此对象并观察更改并在更改时重新呈现?
答案 0 :(得分:2)
您的顶级应用程序将永远不会在引擎更改时重新呈现,因为它存在于React之外。您需要将引擎置于顶层state
,并通过调用setState
进行更改,或使用forceUpdate
api强制React在引擎更改时更新。
如果您愿意将MobX作为额外的依赖项,那么这可能就像将引擎标记为可观察的以及将其作为观察者使用的所有组件一样简单。 (这适用于OP)
作为旁注,看起来你正在做的事与React本身不一致。 React旨在控制您的应用呈现的时间,但您已使用外部引擎来指示何时应呈现内容。如果您要与引擎紧密结合使用独立的虚拟DOM库,则可能会提供更好的服务。也许像lit-html之类的东西。
答案 1 :(得分:0)
每次调用setState()时都会重新渲染,在这种情况下,对象在反应意识之外被更改,你可以让引擎发出一个事件,然后调用setState和/或remodel反应状态中的数据和调用setState来解决它我相信。