我有一个addEvent函数,但没有传递给它的正确状态

问题描述 投票:1回答:1

我的app.js实际上创建了一个小部件布局。它包含一个add函数,用于从状态中获取selectedWidgetId并在一个选项数组中找到它。我有一个handleWidgetSelection函数,它根据外部组件中的选择更新selectedWidgetId状态。例如,如果用户选择“List”,则selectedWidgetId将更新为“List”。我注意到的是在handleWidgetSelection中正在更新状态,但是当我在add函数和控制台日志中使用它时,它显示为原始状态null并且无法在widgetOptions数组中找到它。任何帮助都会很棒。

class App extends Component {
    constructor(props) {
      super(props);
      this.state={
        selectedWidgetId: null,
        widgetOptions:[{name:"Data Table", comp:<DataTable/>},{name:"List", comp:<CheckboxList/>}],

        widgets:[ //array for layout 
          {id:1, content: <DataTable/>},
          {id:2, content: <CheckboxList/>},
          {id:3, content: ""},
          {id:4, content: ""}
        ],
        isModalOpen: false
      }

    }

    handleWidgetSelection=(id) => {

      this.setState({ selectedWidgetId: id }, () => {
        console.log('updated state value', this.state.selectedWidgetId) //this shows up correctly 
       })
    }

    addEvent=(index)=>{
        this.setState({ 
            isModalOpen: true
        })
        const copyWidgets=Object.assign([],this.state.widgets); 
        let widget = Object.assign({}, this.state.widgets[index]);
        console.log(this.state.selectedWidgetId); //this shows up as null 
        widget.content=this.state.widgetOptions.find(w => w.name === this.state.selectedWidgetId).comp;//it is unable to find it in the array because it appears as the original state of null 
        copyWidgets[index]=widget; 
        this.setState({ 
            widgets:copyWidgets

        }) 
    }
   .... 
   render() {
      const { classes } = this.props;

      return (

      <div className={classes.root}>
      <AddWidgetDialog handleWidgetSelection={this.handleWidgetSelection} widgets={this.state.widgetOptions} isModalOpen={this.state.isModalOpen} onRequestClose={this.onRequestClose} />
        <Grid container spacing={24}>
            {
                this.state.widgets.map((widget,index)=>{
                    return(
                        <Grid item xs={12} sm={6}>
                            <Paper className={classes.paper}><Swappable id={widget.id} content={widget.content} delete={this.deleteEvent.bind(this,index)} add={this.addEvent.bind(this,index)}/></Paper>
                         </Grid>
                    )
                })
            }
        </Grid>
      </div>
      );
    }

可交换组件:

import React, { Component } from 'react'

class Swappable extends Component {
    constructor() {
        super()

        this.state = {
            customFunc: null
        }
    }

    allowDrop(ev) {
        ev.preventDefault();
    }

    drag(ev, customFunc = null) {
        ev.dataTransfer.setData("src", ev.target.id);
        console.log(ev.target.parentNode, 'TARGET DRAGSTART')

        this.setState({
            initialParentNode: ev.target.parentNode
        })
    }

    dragEnd(ev, customFunc = null) {

        console.log(ev.target.parentNode, 'TARGET DRAGEND')
        if (customFunc && (ev.target.parentNode != this.state.initialParentNode)) {
            console.log('custom func')
            this.props.customFunc()
        }
    }

    drop(ev, dragableId, dropzoneId, customFunc = null, swappable = true) {
        ev.preventDefault();
        let src = document.getElementById(ev.dataTransfer.getData("src"));
        let srcParent = src.parentNode;
        let target = document.getElementById(dragableId);

        console.log(src, 'dragged element');
        console.log(srcParent, 'parent of dragged');
        console.log(target, 'element to be swapped')

        swappable ? this.swapElements(src, target, srcParent) : this.transferElement(src, dropzoneId)

    }

    swapElements(src, target, srcParent) {
        target.replaceWith(src);
        srcParent.appendChild(target);
    }

    transferElement(src, dropzoneId) {
        let dropzone = document.getElementById(dropzoneId)
        dropzone.appendChild(src);
    }

    render() {
        const dropZoneStyle = {                          
            width: '450px',
            minHeight: '300px',
            padding: '10px',
            border: '1px solid #aaaaaa'
        };

        const draggableStyle = { 
            width: '400px',
            height: '300px',
            padding: '10px',
            border: '1px solid red'
        };

        const { id, content, swappable, customFunc } = this.props
        const dropzoneId = 'drop' + id
        const dragableId = 'drag' + id

        console.log(customFunc, 'customFunc')
        return (
            <div
                id = {dropzoneId}
                onDrop={(event) => this.drop(event, dragableId, dropzoneId, customFunc, swappable)} 
                onDragOver={(event) => this.allowDrop(event)} 
                style={dropZoneStyle}>
                <div id={ dragableId }
                    draggable="true"
                    onDragStart={(event) => this.drag(event)}
                    onDragEnd = {(event) => this.dragEnd(event, customFunc)}
                    style={draggableStyle}>

                    { content }
                    <div>{content==""?<button onClick={this.props.add}>Add Widget</button>:<button onClick={this.props.delete}>Delete</button>}</div>
                </div>
            </div>
        )
    }
}

export default Swappable;

AddWidgetDialog组件:

import React, { PropTypes } from 'react';
import Modal from 'react-modal';

const AddWidgetDialog = ({ handleWidgetSelection, widgets, isModalOpen, onRequestClose}) => {
  const widgetItems = widgets.map((widget) => {
    return (
      <div className="list-group">
      <a href="#" onClick={() => handleWidgetSelection(widget.name)} className="list-group-item">
          <h6 className="list-group-item-heading">{widget.name}</h6>
        </a>
      </div>
    );
  });
  return (
    <Modal
      className="Modal__Bootstrap modal-dialog"
      isOpen={isModalOpen}>
      <div className="modal-content">
       <div className="modal-header">
         <button type="button" className="close" onClick={onRequestClose}>
           <span aria-hidden="true">&times;</span>
           <span className="sr-only">Close</span>
         </button>
         <h4 className="modal-title">Add a widget</h4>
       </div>
       <div className="modal-body">
         <h5>Pick a widget to add</h5>
         {widgetItems}
       </div>
       <div className="modal-footer">
         <button type="button" className="btn btn-default" onClick={onRequestClose}>Close</button>
       </div>
      </div>
    </Modal>
  );
};

export default AddWidgetDialog;
reactjs
1个回答
0
投票

尝试用箭头功能替换这个add={this.addEvent.bind(this,index)}

add={()=> this.addEvent(index)}
© www.soinside.com 2019 - 2024. All rights reserved.