You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用HOC与recompose?React新手的可编辑容器实现疑问

Fixing Your Editable Row HOC with Recompose

Hey there! Since you're new to React and working on an editable container using a Higher-Order Component (HOC) with Recompose, let's sort out that editableRow HOC and get it working properly.

First, Let's Refine the HOC Code

Here's a corrected and complete version of your editableRow HOC with proper state handling and additional helpers for save/cancel actions:

import React from 'react';
import { withStateHandlers, withHandlers, compose } from 'recompose';

const editableRow = () => compose(
  // Manage editing state
  withStateHandlers(
    { 
      isEditing: false, 
      editingId: null 
    },
    {
      toggleEditing: ({ isEditing, editingId }) => (entryId) => ({
        // Toggle editing state: if already editing, turn it off and clear editingId
        isEditing: !isEditing,
        // Only set editingId if we're turning editing ON
        editingId: !isEditing ? entryId : null
      }),
      // Helper to force exit editing state (useful for cancel/save)
      exitEditing: () => () => ({
        isEditing: false,
        editingId: null
      })
    }
  ),
  // Add handlers for save/cancel actions
  withHandlers({
    handleSave: ({ exitEditing }) => (saveCallback, entryData) => {
      // Execute the parent-provided save logic
      if (typeof saveCallback === 'function') {
        saveCallback(entryData);
      }
      // Exit editing state after save
      exitEditing();
    },
    handleCancel: ({ exitEditing }) => () => {
      // Just exit editing without saving
      exitEditing();
    }
  })
);

export default editableRow;

How to Use This HOC

Now wrap your row component with this HOC, and use the injected props to toggle between view and edit modes:

// Example Row component that will be wrapped
const Row = ({ entry, isEditing, editingId, toggleEditing, handleSave, handleCancel }) => {
  const isCurrentEntryEditing = isEditing && editingId === entry.id;

  if (isCurrentEntryEditing) {
    // Render edit form when in editing mode
    return (
      <div className="editable-row">
        <input 
          type="text" 
          defaultValue={entry.name} 
          ref={(input) => { if (input) input.focus(); }}
        />
        <button onClick={() => handleSave(
          (data) => console.log('Saving:', data), 
          { ...entry, name: event.target.previousSibling.value }
        )}>
          Save
        </button>
        <button onClick={handleCancel}>Cancel</button>
      </div>
    );
  }

  // Render view mode when not editing
  return (
    <div className="row">
      <span>{entry.name}</span>
      <button onClick={() => toggleEditing(entry.id)}>Edit</button>
    </div>
  );
};

// Wrap the Row component with our HOC
const EditableRow = editableRow()(Row);

// Use EditableRow in your parent component
const DataTable = ({ entries }) => (
  <div>
    {entries.map(entry => (
      <EditableRow key={entry.id} entry={entry} />
    ))}
  </div>
);

Key Fixes & Explanations

  • Corrected toggleEditing Logic: The original code had an incomplete assignment for editingId — now we only set it when enabling editing, and clear it when disabling.
  • Added exitEditing Helper: A dedicated function to safely exit editing mode, which is reused in save/cancel handlers to avoid code duplication.
  • Explicit Save/Cancel Handlers: These make it easy to integrate with parent component logic (like API calls) while keeping the HOC reusable.
  • Clear Prop Usage: The wrapped Row component checks if the current entry's ID matches editingId to ensure only the clicked row enters edit mode.

Quick Notes

  • Make sure your Recompose version is up to date (though the core functions used here are stable).
  • If you're moving to modern React, keep in mind that Recompose patterns can be replaced with custom hooks, but since you're working with HOCs right now, this approach is solid.

内容的提问来源于stack exchange,提问作者Istvan Orban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:42:53