首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在异步函数完成运行之前对呈现作出反应

在异步函数完成运行之前对呈现作出反应
EN

Stack Overflow用户
提问于 2022-07-23 21:56:11
回答 1查看 158关注 0票数 0

下面的程序从Firebase db读取数据,然后通过setState将其存储到变量中。在第一次呈现时,没有未定义的{problem},因此它不能在代码中使用。这意味着React只会呈现一个带有硬编码文本的页面。一旦运行setState,组件就会重新呈现,程序就会显示数据.唯一的问题是,当我将{ problem }变量传递给子组件时,它会返回以下错误( AdditionalInfo.jsx中最后一行出现错误)。

AdditionalInfo.jsx:45未定义TypeError:无法读取未定义属性(读取“映射”)

为什么程序只返回子组件的错误,我如何修复这个错误?

Problem.jsx

代码语言:javascript
复制
const [problem, setProblem] = useState({});


    useEffect(() => {
        const getProblem = async () => {
            const problemsRef = collection(db, "problems");
            const q = query(problemsRef, where("problemNumber", "==", parseInt(params.id)));
            const querySnapshot = await getDocs(q);
            setProblem({...querySnapshot.docs[0].data()});
        }
        getProblem();
    }, [params.id]);
.
.
.

   return (
        <Split
        gutterSize={10}
        gutterAlign="center"
        cursor="col-resize"
        snapOffset={75}
        className='split'
        minSize={0}>
            <div className="bg-gray-100 min-h-screen max-h-screen overflow-y-auto"> {/* min-h-screen causes there to be a small scroll because of the navbar. To fix this use someting like min-h-screen minus height of navbar */}
                <div className='mx-2 my-2 text-1xl font-medium'>
                    {problem.problemNumber}. {problem.problemTitle}
                </div>
                <div className='mx-2 my-2 text-1xl font-normal text-green-600'>
                    {problem.problemType}
                </div>
                <Divider variant="middle" />
                <div className='mx-2 my-2 text-1xl text-base'>
                    {problem.problemQuestion}
                </div>

                <div>
                    {mapToArray(problem.companies).map(([key, value]) => {
                        return <CompanyTag key={key} companyName={value} companyId={key} />
                    }
                    )}
                </div>
                <AdditionalInfo problem={problem}/>
            </div>
                
            <div className="bg-gray-100">
                <div className='mx-7'>
                    <video width="100%" height="100%px" controls>
                        <source src="movie.mp4" type="video/mp4"></source>
                    </video>
                </div>
            </div>

        </Split>
    )   

AdditionalInfo.jsx

代码语言:javascript
复制
const AdditionalInfo = ({ problem }) => {

  return (
    <div>
        {problem.questionTips.map((tip) => {
            return <Tip key={tip.number} number={tip.number} description={tip.description} />
        })} // Code causes an error here
.
.
.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-23 22:23:04

作为答案回答。

错误的原因是,您最初设置了const [problem, setProblem] = useState({});,因此首先呈现问题的只是一个空对象。在传递problem的子组件中,您试图在jsx中使用problem.questionTips.map() fn,由于在第一次呈现时,problem.questionTips是未定义的--试图访问未定义的.map会导致您的错误。

您应该使用?操作符来解决这个问题。

代码语言:javascript
复制
{problem.questionTips?.map((tip) => {
  return <Tip key={tip.number} number={tip.number} description={tip.description} />
})}

在评论中回答另外一个问题:“是否有一种方法可以完全等待,直到所有数据在呈现之前从火基读取?”

是的,有一种方法,就是用

代码语言:javascript
复制
{problem?.questionTips && <AdditionalInfo problem={problem}/>}

,这在加载带有AdditionalInfo的problem之前不会呈现questionTips组件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73094461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档