【问题标题】:Compilation error with React Redux based on a union type with undefined基于未定义联合类型的 React Redux 编译错误
【发布时间】:2020-12-12 15:46:32
【问题描述】:

我目前正在做一个关于使用 Redux 和 React 的教程,并决定用 Typescript 来做。我收到一个编译错误,我的商店的状态是 {posts: PostType[]} 类型。但是我收到一个错误提示

Type '{ posts: PostType[]; } | undefined' is not assignable to type '{ posts: PostType[]; }'

我不确定该怎么做,因为在我自己的代码中我没有明确建议帖子可能是未定义的。以下是代码中的相关点。

// The component using redux
handleClick = () => {
        const post = this.props.post! as PostType
        this.props.deletePost(post.id)
}

const mapStateToProps = (state: {posts: PostType[]}, ownProps: Props) => {
    return {
        post: state.posts.find(post => {
            return post.id === parseInt(ownProps.match.params.post_id);
        })
    }
}

const mapDispatchToProps = (dispatch: any) => {
    return {
        deletePost: (id: number) => {dispatch({type: 'DELETE_POST', id: id})}
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Post);
// The reducer
import { PostType } from "../components/Home";

const initState = {
    posts: [{id: 1, title: 'Doctors hate him', body: 'Discover the new trick to stay young', userId: 3}, 
            {id: 2, title: 'Fresh donuts', body: 'Hand-glazed', userId: 4}, 
            {id: 3, title: 'Duque dimite', body: 'El presidente colobiano dio su renuncia', userId: 5}]
}

const rootReducer = (state: {posts: PostType[]}  = initState, action: {type: string, id: number}) => { 
    if (action.type === 'DELETE_POST') {
        return {
            ...state,
            posts: state.posts.filter(post => post.id !== action.id)
        }
    }
}   


export default rootReducer;

我注意到的一些奇怪的事情是,如果我从 rootReducer 函数中删除 if 语句,我的代码会很好地转换。我真的很难过。我确实尝试研究过这个问题,但我发现它可能与 --strictNullChecks 标志与 redux 不兼容有关,但我不确定。感谢您的帮助。

编辑:堆栈跟踪+下面的组件

Post.tsx:48 Uncaught TypeError: Cannot read property 'posts' of undefined
    at Function.mapStateToProps [as mapToProps] (Post.tsx:48)

指这个

const mapStateToProps = (state: {posts: PostType[]} , ownProps: Props) => {
    return {
        post: state.posts.find(post => {  // this line causes the error
            return post.id === parseInt(ownProps.match.params.post_id);
        })
    }
}

尽管我认为上面的代码更相关,但我将在下面留下组件代码。

interface PostProps {
    post_id: string
}

interface Props extends RouteComponentProps<PostProps> {
    post?: PostType
    deletePost: (id: number) => void
}

class Post extends Component<Props, {}> {

    handleClick = () => {
        const post = this.props.post! as PostType
        this.props.deletePost(post.id)
    }

    render() {
        let post;
        if (this.props.post !== undefined) {
            const postData = this.props.post! as PostType
            post = 
            <div className="post">
                <h4 className="center">{postData.title}</h4>
                <p>{postData.body}</p>
                <div className="center">
                    <button className="btn grey" onClick={this.handleClick}>Delete Post</button>
                </div>
            </div>;
        } else {
            post = <h4>Loading post...</h4>;
        }
        return (
            <div className="container">
                {post}
            </div>
        );
    }
}

【问题讨论】:

  • 我对 typescript 不熟悉,但基于 ts 错误,您似乎也应该在状态类型中添加 | undefinedconst mapStateToProps = (state: {posts: PostType[] } | undefined , ownProps: Props) =&gt; {
  • 好主意,但我已经尝试过了,即使我这样做了,我仍然得到相同的错误
  • 你也可以分享堆栈跟踪+组件实现吗?

标签: reactjs typescript redux react-redux reducers


【解决方案1】:

事实证明这是我的减速器出错。我之前检查了参数的 action.type,然后返回了一个新状态,但如果它不是那种类型,我返回 void 认为这很好,因为我没有在我的代码。实际上,reducer 是在后台调用的,因此它导致了这个错误,因为现在状态是未定义的。所以总是在 reducer 中默认返回现有状态!

仅在下面进行必要的修复:

const rootReducer = (state: {posts: PostType[]}  = initState, action: {type: string, id: number}) => { 
    if (action.type === 'DELETE_POST') {
        return {
            ...state,
            posts: state.posts.filter(post => post.id !== action.id)
        }
    }
    return {
        ...state      // We do this because the reducer is called by something that was not our dispatch
    }
}   

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多