React Native 踩坑记录

React Native 踩坑记录

Aron Lv3

常见问题快问快答

文字组件内容超出边界

如何解决Text文字内容超出父组件问题?

尝试添加flexShrink: 1到容器和文字的样式.

路由堆栈重置

如何跳转到某个页面,并删除之前的所有页面历史?(比如退出登录后回到首页)

1
2
3
4
5
6
7
import { useNavigation, CommonActions } from '@react-navigation/native';

// name就是要跳转的路由名字
// 这个方法实际上是重置页面历史的,index默认就是0,所以只有一个历史页面
navigation.dispatch(
CommonActions.reset({ index: 0, routes: [{ name: 'PlaceOrder' }] })
);

输入框键盘控制

TextInput默认情况下会在点击输入框范围之外消失,如何禁止这种行为?(比如点击输入框右侧的按钮清空文字,默认情况下,需要点击两次才能达到效果)

如果不介意使用ScrollView的话,可以设置keyboardShouldPersistTaps={'always'},然后keyboardDismissMode={'on-drag'},这样点击就不会收回键盘了,拖动页面的时候才会收回。
如果用了ScrollView但是不希望页面滚动的话,可以设置scrollEnabled={false}禁止滚动;

ref转发

如何转发ref?(外部传入一个ref,我想将其绑定到我的一个子组件上?)

使用React.forwardRef<Ref类型,Props类型>()
示例代码:

1
2
3
4
const SingleSelectBottomSheet = React.forwardRef<BottomSheetModal, SingleSelectBottomSheetProps>((props, ref) => {
// 这样外部传入的ref,引用的其实是这个Modal,然后在外部就可以bottomSheet.present()
return < BottomSheetModal ref={ref} />
})

如何ref我的子组件本身?我想调用子组件的方法?
使用useImperativeHandle hook :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface LoadingToastProperties {
showLoading: () => void;
hide: () => void;
}

interface LoadingToastProps {
loadingText?: string;
}

// forwardRef第一个参数是外界在使用这个ref时,能调用什么样的类型,
// 第二个参数时props类型
const LoadingToast =
React.forwardRef<LoadingToastProperties, LoadingToastProps>((props, ref) => {
/// 这个hook返回类型必须要跟ref也就是LoadingToastProperties定义的一样
useImperativeHandle(ref, () => ({
showLoading: () => {
setDisplay(true);
setLoading(true);
},

hide: () => {},
}),
[]
);

return xxx;
}

React Navigation泛型

怎么写useRoute以及useNavigation的泛型?
升级到react-navigation v6后,泛型必须要写了,否则会报错
useRoute泛型:

1
2
3
4
5
6
7
8
9
10
11
12
13
const route = useRoute<RouteProp<any, any>>();

// 上面这个写法,route.params是个any类型
type ParamList = {
PasswordLogin: {
id: string;
};
}
const route = useRoute<RouteProp<ParamList, 'PasswordLogin'>>();
// 这种写法,route.params的类型是 {id: string}
// 📢📢📢📢:上面的类型定义必须要type,用interface会报错,暂时没弄懂为啥
// 📢📢📢📢:ParamList里面的PasswordLogin跟RouteProp第二个泛型是对应的,否则会报错
// useRoute的方法定义用泛型就达到了这种效果,很神奇

useNavigation泛型:

1
const navigation = useNavigation<NavigationProp<any>>();

注意事项

状态异步

使用hooksetState之后,不要立即使用新的state,新的state会在下一次渲染的时候才有效;

1
2
3
4
5
setCountries(value.data.data);
/// setState是异步的
/// 这里不要立即使用countries,会产生undefined;
// 不要这样写:setPreferredCountry(countries[0]);,要像下面这样用变量
setPreferredCountry(value.data.data[0]);

一些棘手的问题

报错invalid language tag

这个是NumberFormatter的报错,一般是参数传错了。

Reanimated 2 failed to create a worklet, maybe xxxxx

  • 首先检查是不是安装了expo支持的reanimated版本,目前expo SDK 41支持的版本是2.1.0
    • 这个似乎不重要,主要看下面两个
  • 然后要检查babel.config.js里面有没有添加reanimated的plugin,注意plugin要放在数组最后一个
  • 最后如果还是有问题,尝试启动的时候使用expo start --clear清除缓存,这条真的有用;

    输入框输入一个字符后,就会失去焦点

这个问题发生在TextInput渲染在列表内。问题的解决方案是,传参数的时候,不要传render function,传这个render function的执行结果,React Element

1
2
3
ListHeaderComponent={makeListHeaderView}
变成这样:
ListHeaderComponent={makeListHeaderView()}
  • 标题: React Native 踩坑记录
  • 作者: Aron
  • 创建于 : 2021-07-25 01:46:11
  • 更新于 : 2025-10-14 09:29:25
  • 链接: https://likeso.github.io/2021/07/25/react-native-cai-keng-ji-lu/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论