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>
);
}