这个想法
我有一个屏幕,上面有一个"全局"按钮,底部有一些输入。默认情况下,这个"全局"按钮将转到"主页"屏幕。
我希望该按钮的工作方式如下:
[input focused] -> [button changes to 'back']
(当按钮处于"返回"状态时,按下时将模糊输入)[button clicked] -> [input blurred] -> [button changes back to 'home']
.
因此,我需要弄清楚如何在应用程序的任何组件中处理按钮的onPress
。
(With输入我只用Keyboard.dismiss()
就能做到,但这不仅仅是输入,我有一些组件,它们有自己的方式来按下按钮)
我的方法
我已经用contextapi做了这个,但是现在我不知道这是不是一个好主意...
我有一个上下文提供程序,如下所示:
export default function MainButtonControlProvider({ children, goToHome }) {
const [_type, setType] = useState('home');
const [_onPressFn, setOnPressFn] = useState(() => goToHome);
const reset = () => {
setType('home');
setOnPressFn(() => goToHome);
}
const set = ({ type, onPress }) => {
setType(type);
setOnPressFn(() => onPress);
}
return (
<MainButtonControlContext.Provider value={{ _type, _onPressFn, reset, set }}>
{children}
</MainButtonControlContext.Provider>
)
}
"全局"按钮如下所示:
export default function MainButton() {
const { _type, _onPressFn } = useContext(MainButtonControlContext);
const getIcon = () => {
switch (_type) {
case 'home':
return <HomeIcon />
case 'back':
return <ChevronIcon size={32} rotation={-90} />
}
}
return (
<Button icon={getIcon()} onPress={_onPressFn} />
)
}
输入如下:
export default function BasicInput() {
const inputRef = useRef(null);
const { set, reset } = useContext(MainButtonControlContext);
return (
<TextInput
ref={inputRef}
onFocus={() => set({ type: 'back', onPress: () => inputRef.current.blur() })
onBlur={() => reset()}
/>
)
}
问题是
因此,输入被聚焦,它改变了"全局"按钮的外观和onPress
功能。
问题是,在执行set()
或reset()
之后,树中也使用MainButtonControlContext
-rerender中的set()
和reset()
函数的其他组件...
他们这样做是很合乎逻辑的,因为状态被改变了,函数也在上下文提供者中被重新创建了......但是我该如何解决这个问题呢?
我本来可以在set()
和reset()
函数上使用useCallback()
,但是set()
接受参数,并且它们总是不同的,所以这样做没有意义。
所以我需要一个不同的方法🥲
我从未使用过redux,但我认为学习它是一个好主意,所以如果有人有使用它的方法,我不介意为了性能而改变整个应用程序😅
我不明白的是如何处理按钮的onPress
,因为redux状态需要是可序列化的...
- 编辑:**
1.我试着用useState
中的set
替换上下文提供程序中的set()
函数,并用useCallback
Package reset()
,成功了!不再需要重新呈现,但是在更换按钮时设置所有的 prop 是一件痛苦的事情(我现在有2个状态)。如果有人知道如何改变set
函数从useState
一点,而不触发rerenders,请帮助;)
1.我还尝试用useReducer
替换所有的useState
,但是由于某种原因,从useReducer
更改state
不会触发按钮的重新渲染...
1条答案
按热度按时间qni6mghb1#
使用Context API的方法不起作用。我通过将
set
和reset
函数 Package 在useCallback
中修复了使用上下文的组件的重新呈现(我不知道我可以将参数传递给useCallback
😅),但它什么也没做,因为提供程序中的所有组件在状态更改后仍然重新呈现...我甚至尝试记住状态,仍然不起作用。我想我在使用API时遗漏了一些东西。如果有人知道如何处理提供者内部的状态,让我知道,这将是一个很好的教训;)
**我最终使用zustand来存储主按钮所需的状态。**Redux对于这样一个简单的应用程序来说感觉有点过头了,而且我也没有任何经验。
所以我只为主按钮创建了一个存储,如下所示:
然后是元件。这两个元件可以用shallow组合在一条线上。
我担心的一个问题是是否可以存储函数。到目前为止,我在这方面没有问题。我确信在持久化这个存储时会有问题,因为函数是不可序列化的,但这样做是没有意义的:)