Reactjs React useState:保留元素工厂实例之间的状态

Reactjs React useState:保留元素工厂实例之间的状态,reactjs,Reactjs,我想做一个显示错误的钩子。下面是简化的解决方案 useError函数为给定错误的元素获取一个工厂,并返回一个适当的React元素工厂进行渲染 我的问题是,useError每次调用它时都会创建一个新工厂,它需要这样做,因为它会关闭当前的错误。但这会导致在每个添加的错误上都挂载ErrorsDisplay,从而导致其状态重置(可以在示例中看到,当您单击应用程序添加错误时) 我不觉得这很地道,也不知道这是否会给我带来其他问题 我的问题是:有没有一种方法可以在不改变状态的情况下工作,最好是使用相同的api

我想做一个显示错误的钩子。下面是简化的解决方案

useError
函数为给定错误的元素获取一个工厂,并返回一个适当的React元素工厂进行渲染

我的问题是,
useError
每次调用它时都会创建一个新工厂,它需要这样做,因为它会关闭当前的错误。但这会导致在每个添加的错误上都挂载ErrorsDisplay,从而导致其状态重置(可以在示例中看到,当您单击应用程序添加错误时)

我不觉得这很地道,也不知道这是否会给我带来其他问题


我的问题是:有没有一种方法可以在不改变状态的情况下工作,最好是使用相同的api for
useError
或者类似的东西?

这里最好的解决方案是不从useError返回组件,而只返回数据值并直接呈现组件

const useErrors = factory => {
  let [error, setError] = useState([]);

  const addError = e => setError(s => [...s, e]);

  return [error, addError];
};

const ErrorDisplay = props => {
  let [someState, setSomeState] = useState(0);

  useEffect(() => {
    let timeout = setTimeout(() => setSomeState(s => s + 1), 1000);
    return () => clearTimeout(timeout);
  }, [someState]);

  return (
    <div>
      {someState} + {props.errors.length}
    </div>
  );
};

export default function App() {
  let [errors, add] = useErrors();

  return (
    <div className="App" onClick={() => add("my error")}>
      <ErrorDisplay errors={errors} />
    </div>
  );
}
const useErrors=factory=>{
让[error,setError]=useState([]);
const addError=e=>setError(s=>[…s,e]);
返回[错误,加法器];
};
const ErrorDisplay=props=>{
让[someState,setSomeState]=useState(0);
useffect(()=>{
让timeout=setTimeout(()=>setSomeState(s=>s+1),1000);
return()=>clearTimeout(超时);
},[someState]);
返回(
{someState}+{props.errors.length}
);
};
导出默认函数App(){
让[errors,add]=useErrors();
返回(
添加(“我的错误”)}>
);
}

嗯。。。是的,恐怕你是对的。害怕,因为这几乎是显而易见的,我很惭愧我没有想到它:我有点希望我扩展了我的样本,因为我有另一个用例,能够提供一个工厂并返回一个包装好的工厂将是非常好的。不过,我可能会尝试将钩子弯曲到更大的程度……我将针对这个问题发布另一个问题:)钩子非常依赖于闭包,因此有时会导致很多调试问题
const useErrors = factory => {
  let [error] = useState([]);
  let [token, render] = useState(true);

  const addError = e => {
       error.push(e);
       render(!token)
  }

  return [useCallback((props) => factory(error), []), addError];
};
const useErrors = factory => {
  let [error, setError] = useState([]);

  const addError = e => setError(s => [...s, e]);

  return [error, addError];
};

const ErrorDisplay = props => {
  let [someState, setSomeState] = useState(0);

  useEffect(() => {
    let timeout = setTimeout(() => setSomeState(s => s + 1), 1000);
    return () => clearTimeout(timeout);
  }, [someState]);

  return (
    <div>
      {someState} + {props.errors.length}
    </div>
  );
};

export default function App() {
  let [errors, add] = useErrors();

  return (
    <div className="App" onClick={() => add("my error")}>
      <ErrorDisplay errors={errors} />
    </div>
  );
}