javascript - Redux 触发的函数未注册组件当前状态
问题描述
TL;博士
当存储更改触发组件功能时,当前组件状态将被忽略/重置,不允许我使用其状态数据来提供触发功能。
详细描述
这个 react-native 应用程序有一个位于标题 Appbar 堆栈导航器中的按钮,它必须触发当前聚焦的 Screen 具有的功能。问题是这个屏幕在导航方案中非常深入,因此我决定使用 Redux 直接通知屏幕按钮已被按下。这也意味着每次按下此按钮并调度存储切片时,我只能根据 Screen 实现触发任何功能。
如果我从组件中的按钮使用完全相同的功能,它会完美运行。但是,如果我从 redux 存储更改中调用相同的函数,我会得到这个日志:
控制台行为
# component loaded
false
# started writing, this is the component state
h
he
hel
hell
hello
#header button 'create' state change detected
true
#content as viewed by the onPressPublish function
content: ""
Error 400 - Cannot save empty content
#store reset for further use
false
应用栏
export const AppBarStackNavigator = (props) => {
const { toggle } = useSelector(toolbarSelector);
const handleCreatePress = () => {
dispatch(setCreate({ pressed: true }));
}
return (
<Appbar.Header
style={{ backgroundColor: theme.colors.background, elevation: 0 }}
>
<Button
icon="seed"
mode="contained"
// disabled={!contentProps.valid}
onPress={handleCreatePress}
labelStyle={{ color: 'white' }}
style={{
width: 115,
borderRadius: 50,
alignSelf: "flex-end"
}}>
Sembrar
</Button>
</Appbar.Header>
);
}
店铺
import { createSlice } from "@reduxjs/toolkit";
export const toolbarSlice = createSlice({
name: 'toolbar',
initialState: {
create: false
},
reducers: {
setCreate(state, action) {
state.create = action.payload.pressed;
}
}
})
export const { setCreate } = toolbarSlice.actions;
export const toolbarSelector = state => state.toolbar
export default toolbarSlice.reducer;
导航深度组件
import { toolbarSelector, setCreate } from '../store/toolbar';
import { useSelector } from 'react-redux';
// import { useFocusEffect, TabActions, useNavigation } from '@react-navigation/native';
export const DeepComponent = (props) => {
const theme = useTheme();
const { create } = useSelector(toolbarSelector);
return (
<ChildComponent {...props} create={create} setCreate={setCreate} style={{ backgroundColor: theme.colors.background }} />
);
};
它的孩子(函数在哪里)
import { useDispatch, useSelector } from 'react-redux';
export const ChildComponent = (props) => {
const dispatch = useDispatch();
const [content, setContent] = useState(''));
let payload = {};
const onPressPublish = async () => {
try {
console.log(payload);
payload = {
...payload,
content,
// images <- other component states
}
console.log(payload);
const seed = await api.writeOne(payload);
} catch (error) {
console.log(error);
Alert.alert('Could not publish :(', error.message);
}
navigation.goBack();
}
useEffect(() => {
console.log(props.create)
console.log(content)
if (props.create) {
console.log(content)
onPressPublish();
}
return () => {
dispatch(props.setCreate({ pressed: false }));
};
}, [props.create])
const onTextChange = (value, props) => {
// ...
setContent(value);
// ...
}
return (
<TextInput
mode='flat'
placeholder={inputPlaceholder}
multiline
onChangeText={text => onTextChange(text, props)}
keyboardShouldPersistTaps={true}
autoFocus
clearButtonMode='while-editing'>
<ParsedContent content={content} />
</TextInput>
<Button
disabled={!contentProps.valid}
onPress={onPressPublish}>
{buttonText}
</Button>
)
}
解决方案
以下是更改代码的一些建议,您仍然没有在您的问题中提供任何有意义的代码(例如有效负载变量),但这可能会让您知道去哪里。
当您使用 create-react-app 创建应用程序时,您应该有一个 linter 来告诉您何时缺少挂钩中的依赖项,您不应忽略这些警告:
//create onPressPublish when component mounts
const onPressPublish = useCallback(async (content) => {
try {
//removed payload as it makes no sense to create it
// and never use it anywhere
//removed assigning to seed becasue it is never used anywhere
await api.writeOne({ content });
} catch (error) {
console.log(error);
Alert.alert('Could not publish :(', error.message);
}
navigation.goBack();
}, []);
const { create, setCreate } = props;
useEffect(() => {
if (create) {
//passing content
onPressPublish(content);
}
return () => {
dispatch(setCreate({ pressed: false }));
};
}, [
//correct dependencies without linter warnings
content,
dispatch,
onPressPublish,
create,
setCreate,
]);
推荐阅读
- python - Pandas 仅将 1 个表导出到 Excel 但打印所有
- python - 为什么有些 CPython 的 lib 模块在 C 和 Python 中都有实现?
- power-automate - SharePoint 列表项 → 联系人 → 联系人列表
- sql - SQL - 获取具有整数和 varchar 列的所有列中空行的百分比?
- cisco - 用于自动配置 2 个不同交换机的 tftp 配置
- regex - 正则表达式按顺序匹配字符,一个或多个字符连续重复 3 次或更多次
- assembly - 简单的 ARM 程序集启动文件似乎没有到达任何代码
- ruby-on-rails - 从 Solidus 产品过滤器/Rails 数据库查询中删除空选项?
- r - 如何在 R 中附加日期/持续时间拼写
- outlook - Outlook 加载项 cookie 在桌面应用程序中清除,但为什么 localStorage 有效?