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

时间:2021-02-22 23:38:05

标签: reactjs

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

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 中取出 Object 并以这种方式将其删除,但是 keyundefined 的形式返回,即使它是从 props 中解构出来的我正在使用箭头函数来保存它。

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

1 个答案:

答案 0 :(得分:2)

问题

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

<块引用>

我试图构建一个 reducer action,它从 对象并以这种方式将其删除,但即使键返回未定义 虽然它是从道具中解构出来的,而且我使用的是箭头 功能来保存它。

这是因为 React 键(和参考)实际上并不是道具。无法在子组件中访问键。不过,您可以通过几乎任何其他命名道具传递相同的值。请注意下面的解决方案我传递了一个 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:将其 id 传递给 removeObj 回调。

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

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

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

检查移除对象reducer中传递的id负载

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;
  }
};

演示

Edit accessing-the-this-keyword-in-a-react-functional-component

相关问题