Search code examples
reactjsfluxreactjs-flux

Action not being called - flux react


Builder Action positionRComponent not called. Am I doing something wrong? Check out the commentLine inside moveBox function in the BuildView.js

Expecting output: to be printed in console.

Position R Component

Below are the code snippets of BuildView.js and builder-actions.js.

BuildView.js

import React, {PropTypes} from 'react';
import BuilderStore from '../stores/builder-store';
import BuilderActions from '../actions/builder-actions'
import update from 'react/lib/update';
import ItemTypes from './ItemTypes';
import RComponent from './RComponent';
import { DropTarget } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

function getViewRComponents(){
  return( {components: BuilderStore.getViewRComponents()})
}
const rComponentTarget = {
  drop(props, monitor, component) {
    const item = monitor.getItem();
    const delta = monitor.getDifferenceFromInitialOffset();
    const left = Math.round(item.left + delta.x);
    const top = Math.round(item.top + delta.y);
    component.moveBox(item.id, left, top);
  }
};

const wrapper = {
  border: '1px solid grey'
}

function collect(connect, monitor){
  return ({
    connectDropTarget: connect.dropTarget()
  })
}

class BuildView extends React.Component{
  constructor(props){
    super(props);
    this.state = getViewRComponents();
    this._onChange = this._onChange.bind(this);
  }
  moveBox(id, left, top) {

    this.setState(update(this.state, {
      components: {
        [id]: {
          $merge: {
            left: left,
            top: top
          }
        }
      }
    }));
    //CALLING HERE>>> Not getting called
    BuilderActions.positionRComponent.bind(null, this.state.components[id]);

  }
  componentWillMount(){
    BuilderStore.addChangeListener(this._onChange)
  }
  render(){
    const { hideComponentOnDrag, connectDropTarget } = this.props;

    let components = this.state.components.map( (component, index) => {
      return(<RComponent
        key={index}
        id={index}
        left={component.left}
        top={component.top}
        hideComponentOnDrag={hideComponentOnDrag}>
        {component.name}
      </RComponent>);
    })
    return connectDropTarget(
      <div>
        {components}
      </div>

    );
  }
  _onChange(){
    this.setState(getViewRComponents());
  }
  componentWillUnMount(){
    BuilderStore.removeChangeListener(this._onChange())
  }
}
BuildView.propTypes = {
  hideComponentOnDrag: PropTypes.bool.isRequired,
  connectDropTarget: PropTypes.func.isRequired
};

export default DropTarget(ItemTypes.RCOMPONENT,rComponentTarget, collect )(BuildView);

builder-actions.js

import BuilderConstants from '../constants/builder-constants';
import {dispatch, register} from '../dispatchers/builder-dispatcher';

export default {
  addRComponent(component) {
    console.log("Add R Component")
    dispatch({
      actionType: BuilderConstants.ADD_RCOMPONENT, component
    })
  },
  removeRComponent(component){
    dispatch({
      actionType: BuilderConstants.REMOVE_RCOMPONENT, component
    })
  },
  positionRComponent(component){
    console.log("Position R Component");
    dispatch({
      actionType: BuilderConstants.POSITION_RCOMPONENT, component
    })
  }
}

Solution

  • Use call or execute the returned function from bind:

    var f = BuilderActions.positionRComponent.bind(null, this.state.components[id])
    f()
    

    or:

    BuilderActions.positionRComponent.call(null, this.state.components[id]);
    

    The difference is bind doesn't execute but returns a new function with the argument list passed into the new function.

    call basically does a bind then executes, apply is similar but takes an array of arguments.

    Hope it helps.