访问react功能组件中的“this”关键字

IT技术 reactjs
2021-05-18 02:01:55

我试图了解如何制作一个可以从具有功能组件的组件数组中删除自身的组件。这是我正在尝试做的示例代码:

const App = () => {
    <ObjState>
        <ObjectCreator />
        <ObjectList />
    </ObjState>
}

const ObjContext = createContext();

const ObjReducer = (state, { type, payload }) => {
    switch(type) {
        case Types.ADD_OBJ:
            return {
                ...state,
                objects: [...state.objects, payload]
            };
        case Types.REMOVE_OBJ:
            return {
                ...state,
                objects: state.objects.filter(obj => obj !== payload)
            };
        default:
            return state;
    }
}

const ObjState = ({ children }) => {
    const initialState = {
        objects: []
    }

    const [state, dispatch] = useReducer(ObjRecuder, initialState);

    const addObj = (obj) => {
        dispatch({
            type: Types.ADD_OBJ,
            payload: obj
        });
    }

    const removeObj = (obj) => {
        dispatch({
            type: Types.REMOVE_OBJ,
            payload: obj
        });
    }

    return (
        <ObjContext.Provider value={{
            objects: state.objects,
            addObj,
            removeObj
        }}>
            {children}
        </ObjContext.Provider>
    );
}

const ObjCreator = () => {
  const { addObject } = useContext(ObjContext);
  const createObj =() => {
    const obj = (<ObjectTypeA key={uuid()} />);
    addObject(obj);
  }
  return (<button onClick={createObj}>create an object!</button>)
}

const ObjectList = () => {
  const { objects } = useContext(ObjContext)
  return (
    <fragment>
      {objects}
    </fragment>
  )
}

const ObjectTypeA = ({ key }) => {
  const { removeObj } = useContext(ObjContext);
  const removeSelf = () => {
      removeObj(this);
  }
  return (
    <button onClick={removeSelf}>remove me!</button>
  )
}

问题是您无法this在最终Object组件中引用我有唯一的密钥,但我不确定如何正确传递它。我试图建立一个拿着减速动作keyObject并删除它的方式,但key回来的undefined,即使它是props的解构出来,我使用的是箭头功能来保护它。

我觉得我在以错误的方式解决这个问题。

1个回答

问题

我认为当你试图在你的上下文状态中存储看起来是 React 组件的东西时,你偏离了方向,你应该存储对象。对象应该具有唯一的 GUID。这允许 reducer 识别要从状态中删除的对象元素。然后ObjectList应该从存​​储的状态渲染派生的 React 组件。

我试图构建一个 reducer 操作,该操作从 Object 中取出键并以这种方式将其删除,但键返回为未定义,即使它是从 props 中解构出来的,并且我正在使用箭头函数来保留它。

这是因为 React 键(和 refs)实际上并不是props。无法在子组件中访问键。您可以通过几乎任何其他命名props传递相同的值。注意下面的解决方案我传递了一个 React 键一个idprops。

解决方案

ObjectCreator:创建对象,而不是 React 组件

const ObjectCreator = () => {
  const { addObj } = useContext(ObjContext);
  const createObj = () => {
    const obj = {
      id: uuid()
    };
    addObj(obj);
  };
  return <button onClick={createObj}>create an object!</button>;
};

特定对象:将其传递idremoveObj回调。

const MyObject = ({ id }) => {
  const { removeObj } = useContext(ObjContext);
  const removeSelf = () => {
    removeObj(id);
  };
  return (
    <div>
      <button onClick={removeSelf}>remove {id}</button>
    </div>
  );
};

ObjectList:呈现objects映射到 JSX的上下文

const ObjectList = () => {
  const { objects } = useContext(ObjContext);
  return (
    <>
      {objects.map((el) => (
        <MyObject key={el.id} id={el.id} />
      ))}
    </>
  );
};

id在remove object reducer中检查传递的payload

const ObjReducer = (state, { type, payload }) => {
  switch (type) {
    case Types.ADD_OBJ:
      return {
        ...state,
        objects: [...state.objects, payload]
      };
    case Types.REMOVE_OBJ:
      return {
        ...state,
        objects: state.objects.filter((obj) => obj.id !== payload)
      };
    default:
      return state;
  }
};

演示

编辑 accessing-the-this-keyword-in-a-react-functional-component