我有一个React组件,它使用useffect
钩子获取数据,如下所示:
const cache = {key: "data-fetched-using-key"}
function Config({key, options}) {
const [data, setData] = useState();
useEffect(() => {
const fetchedData; // fetch data using key and options
setData(fetchedData);
cache[key] = fetchedData;
}, [key, options])
return <p>{data}</p>;
}
每次键
或选项
更改时,都会运行钩子。但是,我也在本地缓存数据,并且只希望在键
和选项
都更改时运行效果(因为对于每个键/选项组合,数据总是相同的)。
是否有一种干净的方法来依赖于键
和选项
的组合,而不是使用React钩子的键
或选项
?
所有提供的解决方案都很好,但是有一些更复杂的情况,例如,当使用效果函数应该只在依赖关系A和B改变时调用,而它也取决于C的值。
所以我建议使用useffects序列和中间状态为未来的逻辑提供更多的空间。针对被问问题的这一方法的实施将是:
const cache = {key: "data-fetched-using-key"}
function Config({key, options}) {
const [data, setData] = useState();
const [needsUpdate, setNeedsUpdate] = useState(()=>({key:false, option:false}));
useEffect(()=>{
setNeedsUpdate((needsUpdate)=>({...needsUpdate, key:true}));
},[key])
useEffect(()=>{
setNeedsUpdate((needsUpdate)=>({...needsUpdate, options:true}));
},[options])
useEffect(() => {
if (needsUpdate.key && needsUpdate.options){
const fetchedData; // fetch data using key and options
setData(fetchedData);
cache[key] = fetchedData;
setNeedsUpdate(()=>({key:false, option:false}));
}
}, [needsUpdate, key, options])
return <p>{data}</p>;
}
通过这种方式,我们可以在useEffect依赖项上应用几乎任何逻辑,但是它有自己的缺点,即渲染周期很少。
为了在两个值都更改时运行效果,您需要使用以前的值,并在关键点或选项更改时在挂钩内比较它们。
您可以编写一个usePrevious
hook,并将旧状态和以前的状态进行比较,如本文所述:
如何在效果上比较旧值和新值?
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const cache = {key: "data-fetched-using-key"}
function Config({key, options}) {
const [data, setData] = useState();
const previous = usePrevious({key, options});
useEffect(() => {
if(previous.key !== key && previous.options !== options) {
const fetchedData; // fetch data using key and options
setData(fetchedData);
cache[key] = fetchedData;
}
}, [key, options])
return <p>{data}</p>;
}
您可以使用useRef()
创建这种逻辑。考虑以下示例和沙盒:https://codesandbox.io/s/react-hooks-useeffect-with-multiple-reqs-6ece5
const App = () => {
const [name, setName] = useState();
const [age, setAge] = useState();
const previousValues = useRef({ name, age });
useEffect(() => {
if (
previousValues.current.name !== name &&
previousValues.current.age !== age
) {
//your logic here
console.log(name + " " + age);
console.log(previousValues.current);
//then update the previousValues to be the current values
previousValues.current = { name, age };
}
});
return (
<div>
<input
placeholder="name"
value={name}
onChange={e => setName(e.target.value)}
/>
<input
placeholder="age"
value={age}
onChange={e => setAge(e.target.value)}
/>
</div>
);
};
工作流程:
ref
对象,在本例中,它是name
和age
。ref对象是previousValues
useffect
已定义,但我们不提供任何依赖项。相反,只要状态更改为name
或age
,我们就让它执行
useffect
中,我们有条件逻辑来检查name
和age
的先前值/初始值是否与其对应的状态值不同。如果它们很好,我们就执行逻辑(console.log)
(以前的值)
更新为当前值(状态)
当前,只有一个依赖项发生更改时,才会触发。 当两个(或所有)依赖项都已更改时,我如何更新/使用它进行回击?
但是,这样做的缺点是将报告为未使用,可能是因为编译不需要它: 我不能使用依赖项,因为我不希望该依赖项传递性地继承(例如,下游依赖项可以使用log4j等)。我使用尝试了,但结果是相同的警告。 (注意,我还可以为依赖插件设置,但这似乎是一个非常生硬的工具,会隐藏其他潜在的问题。)
在Java10和maven中运行我的Spring boot项目,一切都很好。简单地将JDK从10更改为11会导致以下错误: 我没有使用Spring Webflux框架,以前也不需要任何带有reactor框架的jar。我知道Java 11从JDK中剔除了很多JEE的东西,但这不是那个。 我尝试了SpringBoot 2.0.5版本和最新的里程碑版本(M4)2.1,结果是一样的。我已经更改了Finch
在Synfony 3.3中,DI的新最佳实践 是使用普通构造函数依赖项注入(或控制器中的“操作”注入),而不是通过$this获取公共服务- 如官方留档所见 因此,无需指定服务,因为我们可以在类控制器中键入提示: 这似乎工作得很好,但如果我扩展了一个类并在构造函数中添加了更多参数呢??? 现在我得到一个循环引用错误: [Symfony\Component\DependencyInjection\Ex
是否可能在运行时检索特定maven依赖项的版本? 例如。对于pom.xml: 我想检索具有工件ID的特定依赖项的版本。
我创建了一个Maven项目(可重用库),该项目有许多依赖项(编译时和运行时),它们也可以过渡地依赖于其他许多依赖项。在maven中,我可以在pom中添加依赖项。xml及其可传递依赖关系将自动处理。所以,我将毫无问题地运行。 现在,我有一个非Maven(基于Ant的)项目,上面创建的库(Maven Lib)将使用它。 在这种情况下,运行时间