Reactjs 渲染组件时的反应行为

Reactjs 渲染组件时的反应行为,reactjs,react-redux,Reactjs,React Redux,假设我有以下LoadingIndicator组件: export default function LoadingIndicator({ isLoading, children }) { return isLoading ? ( <div> <LoadingContainer> <Spinner as="span" animation="border" role="status" /> <br /&

假设我有以下
LoadingIndicator
组件:

export default function LoadingIndicator({ isLoading, children }) {
  return isLoading ? (
    <div>
      <LoadingContainer>
        <Spinner as="span" animation="border" role="status" />
        <br />
        <span>Carregando...</span>
      </LoadingContainer>
    </div>
  ) : (
    { children }
  );
}
export default function DocumentsPage() {
  const dispatch = useDispatch();

  const currentUser = useSelector((state) => state.users.current);

  React.useEffect(() => {
    if (!currentUser) dispatch(UsersAction.requestCurrentUser());
  }, [dispatch, currentUser]);

  return (
    <LoadingIndicator isLoading>
      <MyAccountBaseLayout>
        <Wrapper>
          {currentUser.documentsStatus.map((document) => (
            <DocumentCard
              key={document.label}
              label={document.label}
              status={document.status}
            />
          ))}
        </Wrapper>
      </MyAccountBaseLayout>
    </LoadingIndicator>
  );
}

导出默认函数LoadingIndicator({isLoading,children}){
返回卸载(

卡雷甘多。。。 ) : ( {儿童} ); }
现在,我有一个使用此组件的页面示例:

export default function LoadingIndicator({ isLoading, children }) {
  return isLoading ? (
    <div>
      <LoadingContainer>
        <Spinner as="span" animation="border" role="status" />
        <br />
        <span>Carregando...</span>
      </LoadingContainer>
    </div>
  ) : (
    { children }
  );
}
export default function DocumentsPage() {
  const dispatch = useDispatch();

  const currentUser = useSelector((state) => state.users.current);

  React.useEffect(() => {
    if (!currentUser) dispatch(UsersAction.requestCurrentUser());
  }, [dispatch, currentUser]);

  return (
    <LoadingIndicator isLoading>
      <MyAccountBaseLayout>
        <Wrapper>
          {currentUser.documentsStatus.map((document) => (
            <DocumentCard
              key={document.label}
              label={document.label}
              status={document.status}
            />
          ))}
        </Wrapper>
      </MyAccountBaseLayout>
    </LoadingIndicator>
  );
}

导出默认函数DocumentsPage(){
const dispatch=usedpatch();
const currentUser=useSelector((state)=>state.users.current);
React.useffect(()=>{
如果(!currentUser)分派(UsersAction.requestCurrentUser());
},[dispatch,currentUser]);
返回(
{currentUser.documentsStatus.map((文档)=>(
))}
);
}
想法很简单:在加载时渲染加载微调器的内容,否则渲染我们收到的内容。但是,
currentUser
将仅在第一次渲染后的
requestCurrentUser
调用后出现。因为我迭代了
currentUser.documentsStatus
,所以收到了错误
TypeError:无法读取null的属性“documentsStatus”


我认为应该发生的是,使用
currentUser
变量的代码段只应该在prop
isLoading
为false时呈现,但这是错误的。我的问题是:由于
加载指示器的内部逻辑,为什么错误仍然发生?这里最好的方法是什么?

在您的情况下,它总是会陷入此错误,因为在您的状态下(可能)没有任何currentUser.documentsStatus的初始值。您可以设置初始状态,但我猜您不想这样做。在这种情况下,您可以将此数据传递给另一个组件,而不是直接在那里进行映射

return (
  <LoadingIndicator isLoading={isLoading}>
    <MyAccountBaseLayout>
      <Wrapper>
        <DocumentCards currentUser={currentUser} />
      </Wrapper>
    </MyAccountBaseLayout>
  </LoadingIndicator>
);

function DocumentCards({ currentUser }) {
  return currentUser.documentsStatus.map((document) => (
    <DocumentCard
      key={document.label}
      label={document.label}
      status={document.status}
    />
  ));
}
返回(
);
函数文档卡({currentUser}){
返回currentUser.documentsStatus.map((文档)=>(
));
}
我不知道这是否是您想要的策略,但如果不设置初始状态或在映射之前检查数据(我猜您可能不想这样做并使用加载部分),您就没有那么多选项


顺便说一下,我不知道从哪里可以得到
isLoading
,但是
意味着
isLoading
在这个组件中总是正确的。这就是为什么我在我的示例中像
一样使用它,假设某个地方定义了
isLoading

isLoading
来自哪里?在这种情况下,它看起来总是正确的,因为您没有为itThanks分配太多值,创建
DocumentCards
组件解决了问题。另外,我发现我可以使用。关于
的isLoading
,是的,我这样做只是为了强调错误发生的时间。一开始看起来是个好主意,欢迎你。是的,正如我在回答中提到的,您可以检查数据是否存在,但我认为您不想将其与此加载策略混合使用。你当然也有这个选择。