如何在单个对象/状态中存储来自两个组件的数据?

时间:2020-01-01 16:34:57

标签: javascript reactjs

我有一个带有两个控制杆组件的控制杆应用程序。我想在父组件“ App.js”中的单个位置上获得坐标,该坐标将每隔一定间隔进行更新,然后将这些坐标通过socket.io发送到服务器。 我尝试了很多事情,例如使用传递给操纵杆的回调,然后从父组件设置状态。但这不起作用。这些值将分别存储。 我对reactjs有新手知识。

App.js的一部分

class App extends React.Component {


    constructor(props) {
        super(props);

        this.state = {
            connection: 'close',
            view: "joystick",
            logs: [],
            coordinates: {A: {x:0, y:0},
            B: {x:0, y:0}}
        }

        this.socket = socketIOClient({'reconnectionAttempts': 1,});
    }

    getJoystickValue = (coords) => {
        const k = Object.keys(coords)[0]
        this.setState({coordinates[k]: coords[k]})

    }

render () {
<div className="container">
                    <Header status={this.state.connection} viewToggle={this.toggleView}></Header>
                    <div className="pad">
                        <Joystick jname="A" getValues={this.getJoystickValue} socketIO={this.socket}></Joystick>
                        <Log logText={this.state.logs}></Log>
                        <Joystick jname="B" getValues={this.getJoystickValue} socketIO={this.socket}></Joystick>              

                    </div>
                </div>
}
}

Joystick.js

class Joystick extends React.Component {

    constructor(props) {
        super(props);
        this.maxDiff = 50;
        this.dragStart = null;
        this.currentPos = { x: 0, y: 0 };
        this.stick = React.createRef();
        this.stickArea = React.createRef();
    }

    componentDidMount() {
        this.stick.current.addEventListener('mousedown', this.handleMouseDown);
        this.stick.current.addEventListener('touchstart', this.handleMouseDown);
        this.stickArea.current.addEventListener('mousemove', this.handleMouseMove);
        document.addEventListener('mouseup', this.handleMouseUp);
        this.stickArea.current.addEventListener('touchmove', this.handleMouseMove);
        this.stickArea.current.addEventListener('touchend', this.handleMouseUp);


        setInterval(() => {
           this.props.getValues(this.getPosition());
        }, 1500);

    }


    getPosition = () => {
        const nm = this.props.jname;
        const coords = {};
        coords[nm] = this.currentPos;
        return coords;
    }

    checkConstraints = (touchArray) => {
      let touch = null;
      const constraints = this.stickArea.current.getBoundingClientRect();
      for (const point of touchArray) {
         if ((point.clientX < constraints.right && point.clientX > constraints.left)
              && (point.clientY < constraints.bottom && point.clientY > constraints.top)) {
                touch = point
         }
      }

      if (touch) {
        return touch;
      }
      return null;

    }

    handleMouseDown = (event) => {
        this.stick.current.style.transition = '0s';
        if (event.changedTouches) {
            this.dragStart = {
              x: event.changedTouches[0].clientX,
              y: event.changedTouches[0].clientY,
            };
            return;
          }
          this.dragStart = {
            x: event.clientX,
            y: event.clientY,
          };
        };

    handleMouseMove = (event) => {
        if (this.dragStart === null) return;
        event.preventDefault();

        const endtouch = new Event('touchend', {
          view: window,
          bubbles: true,
          cancelable: true
        });

        if (event.changedTouches) {
          const p = this.checkConstraints(event.changedTouches);
          if (!p) {
            this.stick.current.dispatchEvent(endtouch);
            return;
          }
          event.clientX = p.clientX;
          event.clientY = p.clientY;
        }

        const xDiff = event.clientX - this.dragStart.x;
        const yDiff = event.clientY - this.dragStart.y;
        const angle = Math.atan2(yDiff, xDiff);
            const distance = Math.min(this.maxDiff, Math.hypot(xDiff, yDiff));
            const xNew = distance * Math.cos(angle);
            const yNew = distance * Math.sin(angle);
        this.stick.current.style.transform = `translate3d(${xNew}px, ${yNew}px, 0px)`;
        this.currentPos = { x: xNew, y: -yNew };

      };

    handleMouseUp = (event) => {
        if (this.dragStart === null) return;
        this.stick.current.style.transition = '.2s';
        this.stick.current.style.transform = `translate3d(0px, 0px, 0px)`;
        this.dragStart = null;
        this.currentPos = { x: 0, y: 0 };
      };


    render () {
        return (
            <div className="stick-area" ref={this.stickArea}>
            <div id={this.props.jname} className="base">
                <div className="stick" ref={this.stick}></div>
            </div>
            </div>
        );
    }
}

export default Joystick;

编辑:Siva Kondapi Venkata进行的校正工作正常,但是使用socket在通过socket.io发送时,发出的是中间的空坐标对象。 Values as received by server

1 个答案:

答案 0 :(得分:0)

如下更新getJoystickValue方法。取得坐标的当前状态值,合并新数据并更新状态。

getJoystickValue = coords => 
    this.setState({ coordinates: {...this.state.coordinates, ...coords} })
相关问题