PropType.shape({}) 失败警告:类型无效

PropType.shape({}) Failure Warning: Invalid Type

我正在尝试从 Redux-State 中设置道具的 PropType,它是一个如下所示的对象:

sDate = {
        all_day: true,                               //bool
        category: "sCategory",                       //string
        created_at: "2021-07-31T10:06:02.545637Z",   //string
        description: "sDescribtion",                 //string
        end: Sat Jul 31 2021 14:05:00 GMT+0200       //Date
        id: 49,                                      //number
        start: Sat Jul 31 2021 16:05:00 GMT+0200     //Date
        title: "sTitle",                             //string
        type: "sType",                               //string
}

至少,dispatch 之前的 axios.get 请求函数内部是这样的。我也可以读出Component内部对象的内容。我在函数组件中使用它,如下所示。

首先,我尝试将其设置为 PropType.object.isRequired,但收到警告

Warning: Failed prop type: Invalid prop `sDate` of type `array` supplied to `EditDate`, expected `object`.

更改为 PropType.array.isRequired 会导致警告

Warning: Failed prop type: Invalid prop `sDate` of type `object` supplied to `EditDate`, expected `array`.

那时我决定使用 PropTypes.shape({})

在下方,您可以看到具有当前 PropTypes 设置的函数组件

function EditDate(props) {

    useEffect(() => {
        props.getSingleDate(id)
    },[])

    const { id } = useParams();

    return (
        <Fragment>
         ...
        </Fragment>
    );
}

EditDate.propTypes = {
    getSingleDate: PropTypes.func.isRequired,
    deleteDate: PropTypes.func.isRequired,
    sDate: PropTypes.shape({
        all_day: PropTypes.bool.isRequired,
        category: PropTypes.string.isRequired,
        created_at: PropTypes.string,
        description: PropTypes.string.isRequired,
        end: PropTypes.instanceOf(Date).isRequired,
        id: PropTypes.number.isRequired,
        start: PropTypes.instanceOf(Date).isRequired,
        title: PropTypes.string.isRequired,
        type: PropTypes.string.isRequired,
    }),
};

const mapStateToProps = state => ({
    sDate: state.dateReducer.dates
});

export default connect(
    mapStateToProps,
    { getSingleDate, deleteDate }
)(EditDate);


我仍然收到警告

Warning: Failed prop type: Invalid prop `sDate` of type `array` supplied to `EditDate`, expected `object`.

我做错了什么?

我也尝试过更改 Redux-Reducer,因为它可能设置错误:

const initialState = {
    dates: []               //  <-- does this determin what React expects?
};

export default function(state = initialState, action) {
    switch (action.type) {
        case GET_DATES:
            return {
                ...state,
                dates: action.payload
            };
        case GET_SINGLE_DATE:
            state.dates = Object    //  <-- this had no effect in the matter discussed
            return {
                state,
                dates: action.payload
            };
            ...

在上面的示例中,在 case GET_DATES 中,我没有遇到任何问题 action.payload 作为相应组件中的道具(在那里,PropTypes.array 有效)。


编辑:

这个有效:

sDate: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired,

谁能给我解释一下为什么? docs 有点含糊。


编辑 2:

我不得不纠正 Redux Reducer 中的逻辑错误:GET_DATESGET_SINGLE_DATE 确实应该在 Redux 状态中有自己的表示:

const initialState = {
    dates: [],                
    sDate: []                
};
...
...
        case GET_SINGLE_DATE:
            return {
                state,
                sDate: action.payload
            };
            ...

编辑 3:

正如下面的答案所解释的,我不得不更改 Reducer 的 initialSate,i.o。使其正常工作:

const initialState = {
    dates: [],                
    sDate: {}      //now, the initial state is an object, too                
};

因此,正确使用它:

EditDate.propTypes = {
...
  sDate: PropType.object.isRequired,
...
}

如果我没看错的话,我们有一个date变量,它是一个空数组作为初始状态。因此,在 api 调用发生之前,应用程序将理解此变量是一个数组。在 api 调用之后,我们接收到一个对象并将数组替换为数据值。所以我们在这里更改了类型,这会生成警告。

当你使用

sDate: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired,

你只是说你对这个变量的两种类型都满意,这消除了警告,但这并不理想。

要正确解决这个问题,你只需要将一个空对象作为初始状态,这样这个变量在api调用前后都是一个对象。