React360-Redux:Communication between 2 roots components via redux

359 Views Asked by At

I have 2 root components in react360.I have the main panel with information and my products and i have my 3d model.I want to communicate one another.Μore specifically I just want to click on the product then the color from my 3d model changes.At this time, my 3d model has value from the store I have originally defined, but while the price is changing, it is not renewed in the 3d model.for example when the application starts the original color of my model is blue but when I click on the first item it does not change to red. Wrere is the problem?????before after

client.js

   import { ReactInstance } from "react-360-web";
    import { Location } from "react-360-web";

    function init(bundle, parent, options = {}) {
      const r360 = new ReactInstance(bundle, parent, {
        // Add custom options here
        fullScreen: true,
        ...options
      });

      // Render your app content to the default cylinder surface
      r360.renderToSurface(
        r360.createRoot("Center", {
          /* initial props */
        }),
        r360.getDefaultSurface()
      );
      r360.renderToLocation(
        r360.createRoot("React3DView"),
        r360.getDefaultLocation()
      );

      // Load the initial environment
      r360.compositor.setBackground(r360.getAssetURL("360_world.jpg"));
    }

    window.React360 = { init };

index.js

  import { AppRegistry } from "react-360";
    import Center from "./components/center";
    import React3DView from "./components/obj";

    AppRegistry.registerComponent("Center", () => Center);
    AppRegistry.registerComponent("React3DView", () => React3DView);

reducer

initialState = {
  data: [
    { id: 1, value: "MILEPTY.png" },
    { id: 2, value: "cleveland.png" },
    { id: 3, value: "phila.png" },
    { id: 4, value: "raptors.png" },
    { id: 5, value: "rockets.png" }
  ],
  currentinfo: "Hello.Press click on T-shirt to show information",
  currentcolor: "blue"
};
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "INFO":
      if (action.key === 1) {
        return {
          ...state,
          currentinfo: "Milwaukee bucks",
          currentcolor: "red"
        };
      }
      if (action.key === 2) {
        return {
          ...state,
          currentinfo: "Cleveland Cavaliers",
          currentcolor: "green"
        };
      }
      if (action.key === 3) {
        return { ...state, currentinfo: "Philadelphia 76xers" };
      }
      if (action.key === 4) {
        return { ...state, currentinfo: "Toronto Raptors" };
      }
      if (action.key === 5) {
        return { ...state, currentinfo: "Huston Rockets" };
      }

    default:
      return state;
  }
};
export default reducer;

centerPanel

import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import Products from "./products";
import { connect } from "react-redux";

class CenterPanel extends React.Component {
  render() {
    return (
      <View style={styles.panel}>
        <View style={{ flex: 1, flexDirection: "row" }}>
          <View
            style={{
              width: 250,
              height: 600
            }}
          >
            <Text style={{ marginTop: "100" }}>{this.props.currentinfo}</Text>
          </View>
          <View
            style={{
              width: 1000,
              height: 600,
              backgroundColor: "green"
            }}
          >
            <View style={{ flex: 1, flexDirection: "row" }}>
              {this.props.data.map(element => (
                <Products
                  key={element.id}
                  value={element.value}
                  id={element.id}
                />
              ))}
            </View>
          </View>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  panel: {
    // Fill the entire surface
    width: 1000,
    height: 600,
    backgroundColor: "rgba(255, 255, 255, 0.4)"
  }
});
const mapStateToProps = state => {
  return {
    data: state.data,
    currentinfo: state.currentinfo
  };
};
export default connect(mapStateToProps)(CenterPanel);

products

import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import { connect } from "react-redux";

class Products extends React.Component {
  state = {
    img: this.props.value
  };
  render() {
    return (
      <View
        style={styles.panelimages}
        onInput={() => this.props.onText(this.props.id)}
      >
        <Image style={styles.images} source={asset(this.state.img)} />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  panelimages: {
    width: 150,
    height: 150,
    marginTop: 200,
    backgroundColor: "white"
  },
  images: {
    width: 150,
    height: 150
  }
});
const mapDispatchToProps = dispatch => {
  return {
    onText: id => dispatch({ type: "INFO", key: id })
  };
};
export default connect(
  null,
  mapDispatchToProps
)(Products);

center

import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import { createStore } from "redux";
import { Provider } from "react-redux";
import reducer from "../store/reducer";
import CenterPanel from "./centerPanel";

// const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
const store = createStore(reducer);

export default class Center extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <CenterPanel />
      </Provider>
    );
  }
}

objpanel

import React from "react";
import {
  asset,
  AppRegistry,
  StyleSheet,
  Text,
  View,
  VrButton,
  Image
} from "react-360";
import Entity from "Entity";
import { connect } from "react-redux";

class Object3d extends React.Component {
  render() {
    return (
      <View>
        <Entity
          source={{ obj: asset("t-shirt.obj") }}
          style={{
            transform: [{ translate: [-3.5, -3.5, -2.8] }],
            color: this.props.currentcolor -------->here is problem
          }}
        />
      </View>
    );
  }
}
const mapStateToProps = state => {
  return {
    currentcolor: state.currentcolor
  };
};

export default connect(mapStateToProps)(Object3d);

obj

import React from "react";
import { AppRegistry, StyleSheet, Text, View, Image, asset } from "react-360";
import { createStore } from "redux";
import { Provider } from "react-redux";
import reducer from "../store/reducer";
import Object3d from "./objpanel";

// const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
const store = createStore(reducer);

export default class React3DView extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Object3d />
      </Provider>
    );
  }
}
1

There are 1 best solutions below

4
Dan Rubio On

I've tried to do this with redux but in the end I had more problems implementing it than it was worth. In order to implement something like that you would need to follow the code that is described here:

React 360 multi panel example

Additionally, I've implemented what you are trying to do without redux. You can look at the code in this repository and also view the production link here. Its modeled after the react 360 code.

CryptoDashboardVR repo

CryptodashboardVR Multipanel synchronization

Finally, If you still need help, check out my course on React 360. I explain the concepts used. Udemy react 360.

Hope that helps. For now, I would abandon the redux approach until maybe 2.0 comes out.