He estado trabajando en esto en un proyecto sin parar durante un par de días y simplemente no puedo entender lo que está sucediendo. Tengo una matriz de objetos que se mapean y crean elementos React. Dentro de los accesorios de cada elemento hay un conjunto de datos que se pueden usar para determinar si ese elemento tiene un error o no; mi objetivo es mostrar si hay un error. Parece que debido a las promesas en el componente "Error", el estado del componente de error no regresa como cabría esperar. Reconstruí una versión mucho más simplificada de mi aplicación y la vinculé aquí: https://codesandbox.io/s/react-playground-forked-ub4nm?file=/Error.js:179-420
Mi resultado esperado es que cuando liquid-linter devuelve su resultado para la cadena: {% if merge %}test 1 2 3{% endif %}
, es una matriz vacía y el error no debería mostrarse.
Por un lado, si está mutando de estado como lo está en su componente, debe colocarse en un 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;
En segundo lugar, estoy bastante seguro de que su biblioteca no funciona bien...
Dos ejemplos simplificados a continuación. Para el primero, ambos no registrarán ningún error, y para el segundo, ambos registrarán el mismo error. Esto no depende de ti.
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));
Pruébelos . Voltee las declaraciones y observe la salida de la consola.
¡Ahí tienes, esto soluciona tu problema!
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;