Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 访问';这';功能组件中的关键字_Reactjs - Fatal编程技术网

Reactjs 访问';这';功能组件中的关键字

Reactjs 访问';这';功能组件中的关键字,reactjs,Reactjs,我试图理解如何使一个组件能够从一系列具有功能组件的组件中移除自己。以下是我尝试执行的示例代码: const App = () => { <ObjState> <ObjectCreator /> <ObjectList /> </ObjState> } const ObjContext = createContext(); const ObjReducer = (state, { type,

我试图理解如何使一个组件能够从一系列具有功能组件的组件中移除自己。以下是我尝试执行的示例代码:

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>
  )
}
const-App=()=>{
}
常量ObjContext=createContext();
const ObjReducer=(状态,{type,payload})=>{
开关(类型){
案例类型。添加对象:
返回{
……国家,
对象:[…state.objects,有效负载]
};
案例类型。删除对象:
返回{
……国家,
对象:state.objects.filter(obj=>obj!==payload)
};
违约:
返回状态;
}
}
const ObjState=({children})=>{
常量初始状态={
对象:[]
}
const[state,dispatch]=useReducer(ObjRecuder,initialState);
常量addObj=(obj)=>{
派遣({
类型:Types.ADD_OBJ,
有效载荷:obj
});
}
常量removeObj=(obj)=>{
派遣({
类型:Types.REMOVE_OBJ,
有效载荷:obj
});
}
返回(
{儿童}
);
}
常量ObjCreator=()=>{
const{addObject}=useContext(ObjContext);
const createObj=()=>{
常量obj=();
addObject(obj);
}
返回(创建一个对象!)
}
常量对象列表=()=>{
常量{objects}=useContext(ObjContext)
返回(
{objects}
)
}
常量ObjectTypeA=({key})=>{
const{removeObj}=useContext(ObjContext);
常量removeSelf=()=>{
移除OBJ(本);
}
返回(
把我带走!
)
}
问题是您不能在最终的
对象
组件中引用
。 我有唯一的钥匙,但我不知道如何正确地传递它。我试图构建一个reducer操作,从
对象
中取出
,并以这种方式将其删除,但
返回为
未定义
,即使它是从道具中解构出来的,并且我正在使用箭头函数来保留它

我觉得我处理这个问题的方式不对。

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

我试图构建一个从 对象,并以这种方式将其删除,但键返回为未定义 虽然它是用道具解构的,我用的是箭 功能来保存它

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

解决方案 ObjectCreator:创建对象,而不是组件

const ObjectCreator = () => {
  const { addObj } = useContext(ObjContext);
  const createObj = () => {
    const obj = {
      id: uuid()
    };
    addObj(obj);
  };
  return <button onClick={createObj}>create an object!</button>;
};
ObjectList:呈现映射到JSX的上下文
对象

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

你用id/钥匙的东西击中了头部,我没想到他们会剥夺道具的使用权。但是,就我所知,状态中的JSX对象数组没有问题,它们与其他对象一样。可以将所有类型的javascript类型置于状态中,但我不建议这样做。通常的做法是只在状态中使用json数据。它使理解、测试和调试变得更容易。问题是我需要数组包含具有特定回调和功能的不同组件。@JakeBlackwell如果它只是一个简单的JSX文本,我想我可能同意您将它们存储在状态中,但您正试图存储一个实例化的React组件,这基本上是渲染周期中该组件的快照。一旦您尝试执行任何“React-y”操作(如访问/更新状态),由于javascript附件的存在,事情往往会变得有点奇怪。您可以在状态中存储“动态”数据,包括要渲染的组件类型,在映射数据时,只需查找数据应渲染到的组件即可。@JakeBlackwell请参阅。正如Haken指出的那样,特定组件处理获得所需的正确回调。
const ObjectList = () => {
  const { objects } = useContext(ObjContext);
  return (
    <>
      {objects.map((el) => (
        <MyObject key={el.id} id={el.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;
  }
};