React + Redux:无法将even.target.id传递给事件处理程序

时间:2017-06-26 16:47:20

标签: javascript reactjs redux

我有一个组件是一个上下文菜单,另一个组件是一个表。

我正在尝试将event.target.id传递给我的事件处理程序,但我注意到它传入的是上一个event.target.id而不是当前的cellId

我首先将this.state放入handleContextMenu并尝试在onDeleteColumn中更新,然后尝试将其传递到onDeleteRowevent.target.id。但是onDeleteRow的值没有得到保存。所以现在我试着将它直接传递到onDeleteColumnEditableTable.js,但是它说它无法读取未定义的属性。

class EditableTable extends React.Component { constructor(props) { super(props); this.state = { open: false, isOpenContext: false, isOpenHeader: false, } this.handleContextMenu = (event) => { event.preventDefault(); console.log(event.target.id); this.setState({ isOpenHeader: true, anchorEl: event.currentTarget, }); } ........ (within render) timelineRows.map((row, rowIndex) => { ////index is number of rows return <tr id={"row"+" "+rowIndex} key={rowIndex}><td style={tableStyles.numbers}>{rowIndex+1}</td>{ headers.map((title, titleIndex) => { return <input name={"cells"} data-row={rowIndex+1} data-column={titleIndex} id={[rowIndex+1] +" "+ titleIndex} style={tableStyles.header} key={[rowIndex+1] +" "+ titleIndex} defaultValue={row[headers[titleIndex]]} onChange={(event) => this.props.handleTableChange(event.target.id, event.target.value)} onKeyDown={(event) => this.bindKeyboard(event)} ***************************************** onContextMenu={(event) =>this.handleContextMenu(event)} /> ***************************************** }) } </tr> }) ............ (Within return) (Here is my context component) <TableContextMenu openContext={this.state.isOpenContext} anchorEl={this.state.anchorEl} anchorOrigin= {{horizontal:"left",vertical:"top"}} targetOrigin= {{horizontal:"right",vertical:"top"}} ***************************************** onDeleteColumn={(event) => this.props.onColumnDelete(event.target.id)} onDeleteRow={(event) => this.props.onRowDelete(event.target.id)} ****************************************** handleCloseContext={this.closeContext} />

EditableTable Container

const deleteRow = (dispatch, cellId) => { console.log("deleteRow " + cellId); dispatch(tableActions.rowDelete(cellId)); } const deleteColumnByHeader = (dispatch, cellId) => { // console.log(" fsdf"); console.log("header delete " + cellId); dispatch(tableActions.columnHeaderDelete(cellId)); } const mapStateToProps = (state, ownProps) => { let experimentState = state.experimentState; let timeline = experimentState[experimentState.previewId]; return{ timeline_variables: timeline.parameters.timeline_variables, randomize_order: timeline.parameters.randomize_order, sampling: timeline.parameters.sampling, } }; const mapDispatchToProps = (dispatch, ownProps) => ({ onColumnDelete: (cellId) => { deleteColumn(dispatch, ownProps, cellId) }, onRowDelete: (cellId) => { deleteRow(dispatch, ownProps, cellId) }, onColumnDeleteByHeader: (cellId) => { deleteColumnByHeader(dispatch, ownProps, cellId) } }) export default connect(mapStateToProps, mapDispatchToProps)(EditableTable);

public interface CardsRepositoryCustom {
    public Page<Cards> customSearch(CardSearch CardSearch, Pageable page);
}

public interface CardsRepository extends JpaRepository<Cards, Integer>, CardsRepositoryCustom {

}

@Repository
public class CardsRepositoryImpl extends SimpleJpaRepository implements CardsRepositoryCustom{

    public CardsRepositoryImpl(Class<Cards> domainClass, EntityManager em) {
        super(domainClass, em);
    }

    @PersistenceContext
    private EntityManager em;

     @Override
     public Page<Cards> customSearch(CardSearch CardSearch, Pageable page) {
        Specification<Cards> specification = (Root<Cards> root, CriteriaQuery<?> cq, CriteriaBuilder cb) -> {
            ..
        }
        return this.findAll(specification, page);
     }
}


@Service
public class CardsServiceImpl implements CardsService {

    @Autowired
    public CardsServiceImpl(CardsRepository CardsRepository) {
        this.CardsRepository = CardsRepository;
    }

    public CardsRepository CardsRepository;

    @Override
    public Page<Cards> customSearch(CardSearch CardSearch, Pageable page) {
        ...
        return CardsRepository.customSearch(CardSearch, page);
    }
    ...

}

2 个答案:

答案 0 :(得分:0)

由于您已经使用箭头函数将此上下文绑定到handleContextMenu函数,因此您可以将该部分重写为:

    handleContextMenu = (event) => {
      event.preventDefault();
      //more code...
  }

另外,当你将handleContextMenu函数提供给onContextMenu处理程序时,不需要箭头函数,因为(如果你像我写的那样编写上面的函数),这个上下文已被绑定 - 不需要额外的箭头函数。您可以按如下方式重写该代码:

    onContextMenu={this.handleContextMenu}

您可以在此页面底部的https://facebook.github.io/react/docs/handling-events.html

页面底部找到更多相关信息。

如果没有完整的代码来完全重新设计它,我无法确定这就是为什么你的代码不能正常工作,但这只是我看到的一件可以帮助的事情。

答案 1 :(得分:0)

您可以直接在事件处理程序中传递行和列,而不是使用id来确定项的行和列。

这可以通过将onContextMenu=...更改为

来完成
onContextMenu={(event) => this.handleContextMenu(event, rowIndex, titleIndex)

handleContextMenu内,您可以使用行和列调度操作,并将其保存在redux存储中。从那里,您可以在任何组件上使用redux的connect来访问行和列。