Javascript TypeError:无法分解属性';标题';属于';pres[0]';因为它是未定义的。(反应)

Javascript TypeError:无法分解属性';标题';属于';pres[0]';因为它是未定义的。(反应),javascript,reactjs,react-redux,Javascript,Reactjs,React Redux,我是React世界的新手,我正在从事一个愚蠢的项目,以获得一些经验并深入了解这个奇妙的仪器,我也是stackoverflow的新手,这是我在这里的第一篇文章,所以我希望不要犯太多错误 在我的项目中,我有一个ProfileComponent,如下所示: const ProfilePage = () => { const presentationUrl = baseUrl + 'presentation'; const pres = useSelector((sta

我是React世界的新手,我正在从事一个愚蠢的项目,以获得一些经验并深入了解这个奇妙的仪器,我也是stackoverflow的新手,这是我在这里的第一篇文章,所以我希望不要犯太多错误

在我的项目中,我有一个ProfileComponent,如下所示:

    const ProfilePage = () => {

    const presentationUrl = baseUrl + 'presentation';

    const pres = useSelector((state) => state);
    const dispatch = useDispatch();

    const fetchPresentation = async () => {
        const response = await axios
            .get(presentationUrl)
            .catch((err) => {
                console.log('Err', err);
            });
        dispatch(addPresentation(response.data));
        console.log(response.data);
    }

    useEffect(() => {
        fetchPresentation();
    }, []);

    return (
        <div className="profile-page">

            { /* Profile page fixed image (left side) */}
            <div className="image-container col-md-5 col-sm-12">
                <div className="mask">
                </div>
                <div className="main-heading">
                    <h1>PR<span>O</span>FILE</h1>
                </div>
            </div>

            { /* Profile page content (right side) */}
            <div className="content-container col-md-7 col-sm-12">

                { /* PRESENTATION */}
                <ProfilePresentation />

                { /* Footer */}
                <Footer />
            </div>
        </div>
    );
    }
    export const ProfilePresentation = () => {

    const pres = useSelector((state) => state.presentation.presentation);
    console.log(pres[0]);

    const { title, subtitle, image, description } = pres[0];

    return (
        <>
            { /* Presentation */}
            <div className="story clearfix">
                <h2 className="small-heading">{title}</h2>
                <div className="col-lg-11 col-lg-offset-1">
                    <div className="story-content clearfix">
                        <img alt="" src={image} className="col-xs-offset-1 col-sm-offset-0 col-sm-4 col-xs-10" />
                        <div className="col-sm-8 col-xs-12">
                            <h3>{subtitle}</h3>
                            <p>
                                {description}
                            </p>
                            <a href="#" className="hire-me">Hire Me</a>
                            <a href="#">Download Resume</a>
                        </div>
                    </div>
                </div>
            </div>
        </>
    );
}
{
  "presentation": [
        {
            "title": "PRESENTATION",
            "subtitle": "An Awesome Web delevoper on planet",
            "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum.",
            "image": "../../public/assets/images/dp.jpg"
        }
    ]
}
这是ActionTypes.js:

export const ADD_PRESENTATION = 'ADD_PRESENTATION';
这是我的presentationReducer.js:

import * as ActionTypes from '../constants/ActionTypes';

const initialState = {
    presentation: [],
}

export const presentationReducer = (state = initialState, { type, payload }) => {
    switch (type) {
        case ActionTypes.ADD_PRESENTATION:
            return { ...state, presentation: payload };
        default:
            return state;
    }
}
我还有一个本地json服务器,该服务器处于打开状态,其中包含一个db.json文件,如下所示:

    const ProfilePage = () => {

    const presentationUrl = baseUrl + 'presentation';

    const pres = useSelector((state) => state);
    const dispatch = useDispatch();

    const fetchPresentation = async () => {
        const response = await axios
            .get(presentationUrl)
            .catch((err) => {
                console.log('Err', err);
            });
        dispatch(addPresentation(response.data));
        console.log(response.data);
    }

    useEffect(() => {
        fetchPresentation();
    }, []);

    return (
        <div className="profile-page">

            { /* Profile page fixed image (left side) */}
            <div className="image-container col-md-5 col-sm-12">
                <div className="mask">
                </div>
                <div className="main-heading">
                    <h1>PR<span>O</span>FILE</h1>
                </div>
            </div>

            { /* Profile page content (right side) */}
            <div className="content-container col-md-7 col-sm-12">

                { /* PRESENTATION */}
                <ProfilePresentation />

                { /* Footer */}
                <Footer />
            </div>
        </div>
    );
    }
    export const ProfilePresentation = () => {

    const pres = useSelector((state) => state.presentation.presentation);
    console.log(pres[0]);

    const { title, subtitle, image, description } = pres[0];

    return (
        <>
            { /* Presentation */}
            <div className="story clearfix">
                <h2 className="small-heading">{title}</h2>
                <div className="col-lg-11 col-lg-offset-1">
                    <div className="story-content clearfix">
                        <img alt="" src={image} className="col-xs-offset-1 col-sm-offset-0 col-sm-4 col-xs-10" />
                        <div className="col-sm-8 col-xs-12">
                            <h3>{subtitle}</h3>
                            <p>
                                {description}
                            </p>
                            <a href="#" className="hire-me">Hire Me</a>
                            <a href="#">Download Resume</a>
                        </div>
                    </div>
                </div>
            </div>
        </>
    );
}
{
  "presentation": [
        {
            "title": "PRESENTATION",
            "subtitle": "An Awesome Web delevoper on planet",
            "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent volutpat enim arcu, eget tempor nibh congue a. Maecenas faucibus sagittis nibh, in bibendum ex. Donec eu ornare augue, nec cursus arcu. Vivamus accumsan mauris nec nulla bibendum, et eleifend nisl tristique. Pellentesque fringilla lorem id nibh auctor sagittis. Suspendisse non nisl at velit malesuada bibendum.",
            "image": "../../public/assets/images/dp.jpg"
        }
    ]
}
现在,这就是正在发生的事情:

  • 在ProfileComponent中的console.log上(在fetchPresentation常量中),控制台中的打印结果运行良好,并且按照我的意愿返回数据,因此,在这之前,一切都运行良好
  • PresentationComponent:在这里,我开始遇到一些问题,如果我注释掉您在我发布的代码中看到的第6行(const{title,subtitle,image,description}=pres[0];),我在第4行的console.log工作正常,并且返回了我想要的正确数据:
  • 但是,如果我试图使用第6行,我会得到一个错误,这是我文章的标题:

    TypeError:无法分解“pres[0]”的属性“title”,因为它未定义

    const { title, subtitle, image, description } = pres[0] ?? {};
    
    我已经找到了一个解决方案,但我不喜欢它,所以我想从你们那里得到一些提示,帮助我摆脱这个错误。 最终的解决方案将是,而不是第6行,写以下几行

        const title = pres[0]?.title;
        const subtitle = pres[0]?.subtitle;
        const image = pres[0]?.image;
        const description = pres[0]?.description;
    
    通过这种方式,一切都正常工作,但在我只有很少的字段并且只有一行数组的情况下,这是可以接受的


    那么,是否可以使用代码的第6行并进行一些更正,而不是使用所有这些代码?

    基本上,您的初始状态是一个空数组,因此
    pres[0]
    是未定义的,您无法从中解构属性

    const initialState = {
      presentation: [],
    }
    
    您不必使用可选的链接语法来访问嵌套属性,而是可以使用它来提供一个回退值,以便从中解构。这在左侧为null或未定义的情况下提供了一个回退值

    const { title, subtitle, image, description } = pres[0] ?? {};
    

    非常感谢您,现在一切都清楚了,您提出的解决方案非常有效。@Tiberius太棒了!如果此答案已充分解决了您的问题,请随时将其标记为已接受的答案。如果这个解释有帮助的话,那么当你可以的时候,别忘了给它投赞成票。干杯。很好,你告诉我,正如我说我是stackoverflow的新手,我已经接受了你说的答案,但我不能在我达到15点的声誉之前投票,一旦我得到他们,我肯定会投票支持你的答案,因为它对我非常有用。