React 帮助:在映射数组中使用 promises 进行条件渲染

React help: conditional rendering with promises inside a mapped array

我已经在一个项目中马不停蹄地工作了几天,我就是不明白发生了什么。我有一个对象数组,它们被映射并创建 React 元素。每个元素的 props 内携带一组数据,可用于确定该元素是否有错误 - 我的目标是在有错误时显示。似乎由于“错误”组件中的承诺,错误组件的状态没有像我预期的那样返回。我重建了我的应用程序的简化版本并将其链接到此处:https://codesandbox.io/s/react-playground-forked-ub4nm?file=/Error.js:179-420

我的预期结果是,当 liquid-linter returns 是字符串的结果:{% if merge %}test 1 2 3{% endif %},它是一个空数组,不应显示错误。

好了,这解决了你的问题!

import React, { useEffect, useState } from "react";
import liquidlinter from "liquid-linter";

const Error = (props) => {
  const [err, setErr] = useState({ active: false, message: "" });
  useEffect(() => {
    liquidlinter.lintStringPromise(props.data.liquid).then((res) => {
      console.log(props.data.id, res);
      if (!err.active && res.length > 0) {
        setErr({ active: true, message: "There's an error!" });
      }
    });

    return () => setErr({ active: false, message: "" });
  }, [props.data.liquid, props.data.id, err.active]);
  return err.active && <span style={{ color: "red" }}> {err.message}</span>;
};
export default Error;

一方面,如果您像在组件中那样改变状态,它应该放在 useEffect 中。

import React, { useState, useEffect } from "react";
import liquidlinter from "liquid-linter";

const Error = (props) => {
  const [err, setErr] = useState({ active: false, message: "" });

  useEffect(() => {
    liquidlinter.lintStringPromise(props.data.liquid).then((res) => {
      const error = `${props.data.id} : ${res}`;

      if (!err.active && res.length > 0) {
        setErr({ active: true, message: error + props.data.liquid });
      }
    });
  }, [props.data.liquid, props.data.id, err]);

  return err.active && <span style={{ color: "red" }}> {err.message}</span>;
};

export default Error;

其次,我很确定你的库不能正常工作...

下面是两个精简的例子。第一次他们都不会记录错误,第二次他们都记录相同的错误。这不是你。

import liquidlinter from "liquid-linter";

liquidlinter.lintStringPromise("{% if merge %}test 3 2 1{% enddif %}").then(res => console.log(res));
liquidlinter.lintStringPromise("{% if merge %}test 1 2 3{% endif %}").then(res => console.log(res));
import liquidlinter from "liquid-linter";

liquidlinter.lintStringPromise("{% if merge %}test 1 2 3{% endif %}").then(res => console.log(res));
liquidlinter.lintStringPromise("{% if merge %}test 3 2 1{% enddif %}").then(res => console.log(res));

Test他们出来了。翻转语句并观察控制台输出。