react.js - redux的connect方法使用修饰器方法,prop-types会报错?

查看:146
本文介绍了react.js - redux的connect方法使用修饰器方法,prop-types会报错?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

我使用prop-types设置了某些参数是必须的,这时使用修饰器方法获取store中所需的数据时,虽然能够达成最后的结果,但是最开始他会报prop-types的相关的错误,意思就是最开始的时候某些需要有的值却没有,这个是什么的问题?

@connect(state => {
    const { selectedSubreddit, postsBySubreddit } = state;
    const { isFetching, lastUpdated, items: posts } = postsBySubreddit[selectedSubreddit] || {
        isFetching: true,
        items: []
    }
    return {
        selectedSubreddit,
        posts,
        isFetching,
        lastUpdated
    }
})
class AsyncApp extends Component {

    componentDidMount() {
        const { dispatch, selectedSubreddit } = this.props
        dispatch(fetchPostsIfNeeded(selectedSubreddit))
        dispatch(push('Home'))
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.selectedSubreddit !== this.props.selectedSubreddit) {
            const { dispatch, selectedSubrediit } = this.props;
            dispatch(fetchPostsIfNeeded(selectedSubrediit));
        }
    }

    handleChange = (nextSubreddit) => {
        this.props.dispatch(selectSubreddit(nextSubreddit))
    }

    handleRefreshClick = (e) => {
        e.preventDefault();

        const { dispatch, selectedSubreddit } = this.props;
        dispatch(invalidateSubreddit(selectedSubreddit));
        dispatch(fetchPostsIfNeeded(selectedSubreddit));
    }

    render() {
       const { selectedSubreddit, posts, isFetching, lastUpdated } = this.props;
       return (
           <div>
               <Picker value={selectedSubreddit}
                       onChange={this.handleChange}
                       options={[ 'reactjs', 'frontend' ]}
                       />
               <p>
                   {lastUpdated &&
                       <span>
                           Last updated at { new Date(lastUpdated).toLocaleTimeString()}.
                       </span>
                   }
                   {!isFetching &&
                       <a href="#"
                          onClick={this.handleRefreshClick}>
                           Refresh
                       </a>
                   }
               </p>
               {isFetching && posts.length === 0 &&
                   <h2>Loading</h2>
               }
               {!isFetching && posts.length === 0 &&
                   <h2>Empty</h2>
               }
               {posts.length > 0 &&
                   <div style={{ opacity: isFetching ? 0.5 : 1}}>
                       <Posts posts={posts} />
                   </div>
               }
           </div>
       )
    }
}

AsyncApp.propTypes = {
    selectedSubreddit: PropTypes.string.isRequired,
    posts: PropTypes.array.isRequired,
    isFetching: PropTypes.bool.isRequired,
    lastUpdated: PropTypes.number,
    dispatch: PropTypes.func.isRequired
}

以上我设置了propTypes,其中selectedSubreddit、posts等参数是必须的。

npm run start 之后,我进入这个组件的页面,虽然能获取到应该有的数据,但是console中会报如下错误:

Warning: Failed prop type: The prop `selectedSubreddit` is marked as required in `Connect(AsyncApp)`, but its value is `undefined`.
    in Connect(AsyncApp) (created by Route)
    in Route (at RouterExample.js:24)
    in div (at RouterExample.js:17)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (at RouterExample.js:16)
    in Provider (at RouterExample.js:15)
    in BasicExample (at App.js:37)
    in div (at App.js:28)
    in App (at index.js:7)
__stack_frame_overlay_proxy_console__ @ proxyConsole.js:56
printWarning @ warning.js:36
warning @ warning.js:60
checkReactTypeSpec @ checkReactTypeSpec.js:80
validatePropTypes @ ReactElementValidator.js:162
createElement @ ReactElementValidator.js:216
render @ Route.js:100
(anonymous) @ ReactCompositeComponent.js:795
measureLifeCyclePerf @ ReactCompositeComponent.js:75
_renderValidatedComponentWithoutOwnerOrContext @ ReactCompositeComponent.js:794
_renderValidatedComponent @ ReactCompositeComponent.js:821
_updateRenderedComponent @ ReactCompositeComponent.js:745
_performComponentUpdate @ ReactCompositeComponent.js:723
updateComponent @ ReactCompositeComponent.js:644
receiveComponent @ ReactCompositeComponent.js:546
receiveComponent @ ReactReconciler.js:124
updateChildren @ ReactChildReconciler.js:109
_reconcilerUpdateChildren @ ReactMultiChild.js:206
_updateChildren @ ReactMultiChild.js:310
updateChildren @ ReactMultiChild.js:297
_updateDOMChildren @ ReactDOMComponent.js:942
updateComponent @ ReactDOMComponent.js:760
receiveComponent @ ReactDOMComponent.js:722
receiveComponent @ ReactReconciler.js:124
_updateRenderedComponent @ ReactCompositeComponent.js:753
_performComponentUpdate @ ReactCompositeComponent.js:723
updateComponent @ ReactCompositeComponent.js:644
performUpdateIfNecessary @ ReactCompositeComponent.js:560
performUpdateIfNecessary @ ReactReconciler.js:156
runBatchedUpdates @ ReactUpdates.js:150
perform @ Transaction.js:143
perform @ Transaction.js:143
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
closeAll @ Transaction.js:209
perform @ Transaction.js:156
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates @ ReactUpdates.js:97
dispatchEvent @ ReactEventListener.js:147
proxyConsole.js:56 Warning: Failed prop type: The prop `posts` is marked as required in `Connect(AsyncApp)`, but its value is `undefined`.
    in Connect(AsyncApp) (created by Route)
    in Route (at RouterExample.js:24)
    in div (at RouterExample.js:17)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (at RouterExample.js:16)
    in Provider (at RouterExample.js:15)
    in BasicExample (at App.js:37)
    in div (at App.js:28)
    in App (at index.js:7)
__stack_frame_overlay_proxy_console__ @ proxyConsole.js:56
printWarning @ warning.js:36
warning @ warning.js:60
checkReactTypeSpec @ checkReactTypeSpec.js:80
validatePropTypes @ ReactElementValidator.js:162
createElement @ ReactElementValidator.js:216
render @ Route.js:100
(anonymous) @ ReactCompositeComponent.js:795
measureLifeCyclePerf @ ReactCompositeComponent.js:75
_renderValidatedComponentWithoutOwnerOrContext @ ReactCompositeComponent.js:794
_renderValidatedComponent @ ReactCompositeComponent.js:821
_updateRenderedComponent @ ReactCompositeComponent.js:745
_performComponentUpdate @ ReactCompositeComponent.js:723
updateComponent @ ReactCompositeComponent.js:644
receiveComponent @ ReactCompositeComponent.js:546
receiveComponent @ ReactReconciler.js:124
updateChildren @ ReactChildReconciler.js:109
_reconcilerUpdateChildren @ ReactMultiChild.js:206
_updateChildren @ ReactMultiChild.js:310
updateChildren @ ReactMultiChild.js:297
_updateDOMChildren @ ReactDOMComponent.js:942
updateComponent @ ReactDOMComponent.js:760
receiveComponent @ ReactDOMComponent.js:722
receiveComponent @ ReactReconciler.js:124
_updateRenderedComponent @ ReactCompositeComponent.js:753
_performComponentUpdate @ ReactCompositeComponent.js:723
updateComponent @ ReactCompositeComponent.js:644
performUpdateIfNecessary @ ReactCompositeComponent.js:560
performUpdateIfNecessary @ ReactReconciler.js:156
runBatchedUpdates @ ReactUpdates.js:150
perform @ Transaction.js:143
perform @ Transaction.js:143
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
closeAll @ Transaction.js:209
perform @ Transaction.js:156
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates @ ReactUpdates.js:97
dispatchEvent @ ReactEventListener.js:147
proxyConsole.js:56 Warning: Failed prop type: The prop `isFetching` is marked as required in `Connect(AsyncApp)`, but its value is `undefined`.
    in Connect(AsyncApp) (created by Route)
    in Route (at RouterExample.js:24)
    in div (at RouterExample.js:17)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (at RouterExample.js:16)
    in Provider (at RouterExample.js:15)
    in BasicExample (at App.js:37)
    in div (at App.js:28)
    in App (at index.js:7)
__stack_frame_overlay_proxy_console__ @ proxyConsole.js:56
printWarning @ warning.js:36
warning @ warning.js:60
checkReactTypeSpec @ checkReactTypeSpec.js:80
validatePropTypes @ ReactElementValidator.js:162
createElement @ ReactElementValidator.js:216
render @ Route.js:100
(anonymous) @ ReactCompositeComponent.js:795
measureLifeCyclePerf @ ReactCompositeComponent.js:75
_renderValidatedComponentWithoutOwnerOrContext @ ReactCompositeComponent.js:794
_renderValidatedComponent @ ReactCompositeComponent.js:821
_updateRenderedComponent @ ReactCompositeComponent.js:745
_performComponentUpdate @ ReactCompositeComponent.js:723
updateComponent @ ReactCompositeComponent.js:644
receiveComponent @ ReactCompositeComponent.js:546
receiveComponent @ ReactReconciler.js:124
updateChildren @ ReactChildReconciler.js:109
_reconcilerUpdateChildren @ ReactMultiChild.js:206
_updateChildren @ ReactMultiChild.js:310
updateChildren @ ReactMultiChild.js:297
_updateDOMChildren @ ReactDOMComponent.js:942
updateComponent @ ReactDOMComponent.js:760
receiveComponent @ ReactDOMComponent.js:722
receiveComponent @ ReactReconciler.js:124
_updateRenderedComponent @ ReactCompositeComponent.js:753
_performComponentUpdate @ ReactCompositeComponent.js:723
updateComponent @ ReactCompositeComponent.js:644
performUpdateIfNecessary @ ReactCompositeComponent.js:560
performUpdateIfNecessary @ ReactReconciler.js:156
runBatchedUpdates @ ReactUpdates.js:150
perform @ Transaction.js:143
perform @ Transaction.js:143
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
closeAll @ Transaction.js:209
perform @ Transaction.js:156
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates @ ReactUpdates.js:97
dispatchEvent @ ReactEventListener.js:147
proxyConsole.js:56 Warning: Failed prop type: The prop `dispatch` is marked as required in `Connect(AsyncApp)`, but its value is `undefined`.
    in Connect(AsyncApp) (created by Route)
    in Route (at RouterExample.js:24)
    in div (at RouterExample.js:17)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (at RouterExample.js:16)
    in Provider (at RouterExample.js:15)
    in BasicExample (at App.js:37)
    in div (at App.js:28)
    in App (at index.js:7)

虽然实际并不影响,但是看着碍事儿,请问怎么解决?

添加一下reducers中的代码:

function selectedSubreddit(state = 'reactjs', action) {
    switch (action.type) {
        case SELECT_SUBREDDIT:
            return action.subreddit
        default:
            return state
    }
}

function posts(state = {
    isFetching: false,
    didInvalidate: false,
    items: []
}, action) {
    switch (action.type) {
        case INVALIDATE_SUBREDDIT:
            return Object.assign({}, state, {
                didInvalidate: true
            })
        case REQUEST_POSTS:
            return Object.assign({}, state, {
                isFetching: true,
                didInvalidate: false
            })
        case RECEIVE_POSTS:
            return Object.assign({}, state, {
                isFetching: false,
                didInvalidate: false,
                items: action.posts,
                lastUpdated: action.receivedAt
            })
        default:
            return state
    }
}

function postsBySubreddit(state = { }, action) {
    switch (action.type) {
        case INVALIDATE_SUBREDDIT:
        case RECEIVE_POSTS:
        case REQUEST_POSTS:
            return Object.assign({}, state, {
                [action.subreddit]: posts(state[action.subreddit], action)
            })
        default:
            return state
    }
}

// 正确的方式是在reducer的文件中直接组合所有reducers
const rootReducer = combineReducers({
    postsBySubreddit,
    selectedSubreddit,
    routerReducer
})

reducers是否要加入初始值

解决方案

这是一个警告:
The prop selectedSubreddit is marked as required in Connect(AsyncApp), but its value is undefined.
这个属性selectedSubreddit被标记为必须的 但是值为undefined。
就说让你给他设置一个默认值。
AsyncApp.defaultProps = {
selectedSubreddit:xxx,
dispatch:xxx
}

这篇关于react.js - redux的connect方法使用修饰器方法,prop-types会报错?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆