首页 > 解决方案 > 在反应功能组件中访问“this”关键字

问题描述

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

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组件中引用。我有唯一的密钥,但我不确定如何正确传递它。我试图构建一个减速器动作,它key从 the 中Object取出并以这种方式删除它,但即使它从道具中解构出来,我也使用箭头函数来保存它keyundefined

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

标签: reactjs

解决方案


问题

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

我试图构建一个 reducer 操作,从 Object 中获取密钥并以这种方式删除它,但是即使它从道具中解构出来并且我正在使用箭头函数来保留它,key 仍以未定义的形式返回。

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

解决方案

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

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

SpecificObject:将其传递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;
  }
};

演示

编辑访问-this-keyword-in-a-react-functional-component


推荐阅读