是否有一个函数返回一个承诺,当在 React Native 中应用了对组件的任何未决更改时,该承诺得到解决?
Posted
技术标签:
【中文标题】是否有一个函数返回一个承诺,当在 React Native 中应用了对组件的任何未决更改时,该承诺得到解决?【英文标题】:Is there a function that returns a promise which gets resolved when any pending changes to a component have been applied in React Native? 【发布时间】:2021-07-11 11:50:28 【问题描述】:我想显示一个自定义输入组件,然后在单击按钮时调用它的方法:
const Parent = () =>
const customInputRef = useRef(null);
const [customInputVisible, setCustomInputVisible] = useState(false);
async function onPress()
setCustomInputVisible(true);
await resolvePendingChanged(); // customInput is not null and can be accessed
customInputRef.current.customMethod();
return (
<View>
<Button onPress=onPress>Press me!</Button>
customInputVisible && <CustomInput ref=customInputRef />
</View>
);
我看到人们使用custom forceUpdate function 来触发组件更新,但这对我来说并没有真正的帮助。
在Svelte 中有这个"tick" lifecycle hook 正是我需要的。
它返回一个承诺,该承诺会在任何未决状态时立即解决 更改已应用于 DOM(或立即,如果没有 等待状态更改)。
React 中是否有与 Svelte 的 tick
等效的方法,如果没有,我如何在 React 中解决这个问题?
【问题讨论】:
【参考方案1】:您可以创建一个使用callback ref 的自定义钩子来设置实际的引用,并解决一个承诺:
const forwardRef, useImperativeHandle, useRef, useState, useCallback, useMemo = React;
const CustomInput = forwardRef((props, ref) =>
const inputRef = useRef();
useImperativeHandle(ref, () => (
customMethod: () =>
inputRef.current.focus();
), []);
return <input ref=inputRef />;
);
class Deferred
constructor()
this.promise = new Promise((resolve, reject) =>
this.resolve = resolve;
this.reject = reject;
);
const waitForComponent = () =>
const componentRef = useRef(null);
return useMemo(() =>
let deferred = new Deferred();
return
waitLoad(ref)
componentRef.current = ref;
if (ref) deferred.resolve();
else deferred = new Deferred(); // create new Promise when ref is null
,
isLoaded: () => deferred.promise,
componentRef
;
, []);
const Parent = () =>
const waitLoad, componentRef, isLoaded = waitForComponent();
const [customInputVisible, setCustomInputVisible] = useState(false);
function onPress()
setCustomInputVisible(visible => !visible);
// use async here - SO snippet doesn't support async await
isLoaded().then(() => componentRef.current.customMethod());
return (
<div>
<button onClick=onPress>Press me!</button>
customInputVisible && <CustomInput ref=waitLoad />
</div>
);
;
ReactDOM.render(
<Parent />,
root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
【讨论】:
非常感谢您的回复!但是,这仅在您希望在customInputVisible
为 true
时始终调用 customMethod()
时才有效。但是,这不是我的情况。我想确保 customMethod()
仅被称为 onPress
而不是在 customInputVisible
更改时。
它有效,非常感谢!这是一个超级聪明的解决方案,虽然我很惊讶你必须为如此简单的任务编写如此多的逻辑。这可以通过 Svelte 和 Angular 中的一行来解决。还是不明白为什么 React 是最受欢迎的前端库。 ?
因为它是 React 中的一个边缘案例,你很少遇到。另外,现在你有了一个可重复使用的钩子,如果你以后遇到类似的问题,你可以使用它。
嗯,也许你是对的,虽然对我来说看起来很常见。我必须在几个不同的项目中执行此操作,例如,关注嵌套输入,或者在这种情况下,我必须在单击“回复”按钮时添加用户标签 (@user)。无论如何,再次非常感谢!节省了我很多时间!以上是关于是否有一个函数返回一个承诺,当在 React Native 中应用了对组件的任何未决更改时,该承诺得到解决?的主要内容,如果未能解决你的问题,请参考以下文章
React Native AsyncStorage getItem 返回承诺而不是值