Not able to change models after loading the scene

I am writing a function in which on button click present models get deleted and new list of model should render on the screen but once the scene is loaded I am able to delete the models but I am not able to render new models.
I am using react-babylon.js
I have used “this.forceUpdate();” to again call the render function of the class.This function calls the render function but the scene and other components are not rendered again.Scene remain static.
Is there any solution to this problem?

We will need a repro or more info :slight_smile:
pinging @brianzinn

var data = [“Bike.glb”, “Alloy_T_01.glb”, “Headlight_T_01.glb”, “Seat_T_01.glb”, “Silencer_T_01.glb”];

class DefaultPlayground extends Component {

constructor(props) {

    super(props)

    this.state = {

        meshes: [],

        modelCollection: []

    }

    this.modelChangeHandler = this.modelChangeHandler.bind(this);

}

renderModel() {

    let baseUrl = "http://localhost:3000/assets/";

    var modelScale = 1;

    var modelPosition = new Vector3(0, 0, 0);

    var modelScaling = new Vector3(modelScale, modelScale, modelScale);

    var modelRotation = new Vector3(0, -15, 0);

    let listOfModel = []

    data.forEach((model, index) => {

        let modelRender = <Model key={index}

            rotation={modelRotation} position={modelPosition} scale={modelScaling}

            rootUrl={`${baseUrl}bike/`} sceneFilename={model} onModelError={this.onModelError}

            onModelLoaded={this.onModelLoaded} onLoadProgress={this.onLoadProgress} onCreated={this.onCreated}

        />;

        listOfModel.push(modelRender);

    })

    return listOfModel;

}

modelChangeHandler() {

    alert("Model change")

    console.log(data)

    let obj = "Alloy_T_01.glb";

    let replaceObj = "Alloy_T_02.glb";

    let newList = data.filter(model => model != obj)

    newList.push(replaceObj)

    data = newList;

    let modelCollection = this.state.modelCollection

    for (let j = 0; j < modelCollection.length; j++) {

        modelCollection[j].dispose();

    }

    console.log(data)

    this.forceUpdate();

}

render() {

    return (

        <div style={{ height: '100%', width: '100%' }}>

            <Engine antialias adaptToDeviceRatio canvasId='babylonJS' style={{ height: '100%', width: '100%' }} >

                <Scene canvasId="scene_1" style={{ height: '100%', width: '100%' }} onMeshPicked={this.meshPicked} >

                    <ArcRotateCamera name="arc" target={new Vector3(0, 1, 0)} minZ={0.001} alpha={(-Math.PI / 2) + 0.5}

                        beta={(0.5 + (Math.PI / 4))} radius={10} lowerBetaLimit={(Math.PI / 2) - 1.5}

                        upperBetaLimit={(Math.PI / 2)} lowerRadiusLimit={5} upperRadiusLimit={15} />

                    <HemisphericLight name='hemi' direction={new Vector3(0, -1, 0)} intensity={0.8} />

                    {this.renderModel()}

                    <EnvironmentHelper options={{ enableGroundShadow: true, groundYBias: 1 }} mainColor={Color3.FromHexString("#74b9ff")} />

                </Scene>

            </Engine>

        </div>

    );

}

I think if you don’t use index for the key and instead use something unique for the model that it will work.

return data.map(model => <Model key={model.fileName} ... />)

To get an idea - look at the ‘key’ on the cubeTexture for the skybox, so when you change the skybox image, the react-reconciler takes care of loading a new texture.

There is a demo running here when you click on the buttons:
https://brianzinn.github.io/react-babylonjs/?path=/story/babylon-basic--skybox

In that demo whenever the rootUrl is changed, react-babylonjs takes care of loading a new texture for you automatically and your JSX looks like this:

<Skybox rootUrl={state.textureUrl} />

There is a similar change needed to pick up the state for shadow casters from your other question. I think the general guideline is to never use index for a key, because the react-reconciler cannot decide what to diff out.

Yes,you are ryte :).After using the unique key I am able to render the model

1 Like