React> 16.8:如何为调度功能创建组件

时间:2019-12-10 08:06:20

标签: javascript reactjs react-hooks

我正在尝试创建一个仅带有reducer函数的组件,可以将其导入某些组件以供使用。

我使用Context API创建了这样的组件:

import React, { useReducer, useContext } from 'react';

import Regress from '../dataObjects/regress';
import { reducer } from './reducer';

const RegressContext = React.createContext();
const RegressConsumer = RegressContext.Consumer;

function RegressProvider(props) {
  const { regressObject } = props;
  const [regress, dispatchToRegress] = useReducer(reducer, !regressObject ? new Regress() : regressObject);

  return(    
      <RegressContext.Provider value={[regress, dispatchToRegress]}>
          {props.children}
      </RegressContext.Provider>
  );
}

const useRegress = () => {
  const contextValue = useContext(RegressContext);
  return contextValue;
};
export { RegressContext, RegressProvider, RegressConsumer, useRegress };

我有一个用于reducer函数的JS,如下所示:


export const reducer = (regress, action) => {
  //some logic
};

我想要实现的是一个新的JS / JSX文件,如下所示:

import React, { useCallback } from 'react';
import { useRegress } from './useRegress';

export const UpdateProperty = (identifier, item) => { 
    const [,dispatchToRegress] = useRegress();

    const updateProperty = useCallback((identifier, item) => { dispatchToRegress({ type: "update", identifier: identifier, payload: item });
    }, [dispatchToRegress]);

    return (updateProperty);
};

如果这样做,则会出现以下错误:

  

未捕获的永久违反:无效的挂接调用。挂钩只能在功能组件的主体内部调用。可能由于以下原因之一而发生:   1.您的React和渲染器版本可能不匹配(例如React DOM)   2.您可能违反了《钩子规则》   3.您可能在同一应用中拥有多个React副本

我如何创建一个包含所有reducer功能的文件,并包装在useCallback中,以便可以在任何组件中使用?

非常感谢您!

编辑:

在随机组件中,我想这样使用它:

import React from "react";
import { UpdateProperty } from '../components/reducerCommands';

const RequestInfo = (props) => {   

    return (
                <Select updateDispatcher={UpdateProperty} />
    );
}
export default RequestInfo

不是像这样直接在组件内部声明调度函数:

import React from "react";
import { UpdateProperty } from '../components/reducerCommands';

const RequestInfo = (props) => {   

    const updateState = useCallback((newState) => {
        dispatchToRegress({ type: "updateState", newState: newState });
    }, [dispatchToRegress]);  

    return (
<Select updateDispatcher={updateProperty} />
    );
}
export default RequestInfo

0 个答案:

没有答案