目录

React Native笔记

Q:JSON转JavaScript对象时自定义key

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const jsonString = '{"componentName":"abc","theme":"light","debugMode":"1"}';
const obj = JSON.parse(jsonString, function (k, v) {
  if (k == "theme") {
    // 给自定义的属性赋值
    this.custom = v;
    // 返回undefined会把当前这个key从对象中移除
    return undefined;
  } else if (k == "") {
    console.log("宝儿姐");
  }
  return v;
});

console.log(obj);

Q:对象如何判空?

1
2
3
4
5
let obj;

console.log(obj == null); // true
console.log(obj == undefined); // true
console.log(obj == false); // false

Q:?? 与 || 区别

?? 只有当valuenullundefined时才会取后面的值,而 || 则认为nullundefined0""false 这些都是false

Q:JS数组取值需要注意越界问题吗?

不需要,JS的数组不会发生越界的异常,我们使用时只需关注数组是否 undefined的问题。

1
2
const arr = [];
console.log(arr[0]); // undefined

undefined问题:

/images/reactnative/undefined.webp
undefined

解决办法:

1
2
const arr = undefined;
console.log(arr?.[0]); // undefined

Q:JS中如何判断一个变量是数组还是对象?

1
2
3
4
const arr = [];
const obj = {};

console.log(Array.isArray(arr)); // true

Q:<> vs React.flagment

  1. 相同点:
  • 都可以包裹子元素
  • 都不渲染任何真实的DOM标签
  • 性能提升
  1. 不同点:
  • React.flagment支持设置key属性

fragment可以解决我们什么问题?

map函数中的组件需要设置key属性,<> 并不支持设置属性,而我们又不想增加DOM节点,此时React.fragment就可以大展身手了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<Text style={style} numberOfLines={numberOfLines}>
    {icons?.map(({ width, height, url }, index) => {
        return (
            <React.fragment key={index.toString()}>
                <Image
                    style={styles.iconImg}
                    resizeMode={'contain'}
                    source={{
                        uri: url,
                    }}
                />
                <Text>&nbsp;</Text>
            </React.Fragment>
        );
    })}

    {props.children ?? ''}
</Text>

Q:hook函数不让在函数中使用怎么办?

使用useMutation

 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
28
29
30
31
32
33
34
export function useQueryProviderNextPage() {
    const bookId = 123
    const dispatch = useAppDispatch();
    return useMutation(
        (params: IParams) => {
            return request({
                method: 'POST',
                url: '/a/b/c',
                params: {
                    id: bookId,
                    currentPage: params.currentPage ?? 2,
                },
            });
        },
        {
            onSuccess: (response) => {
                if (response) {
                    dispatch(updateProviderList(response.data));
                }
            },
            onError: (response) => {
                console.log('--- 请求失败---', console.log(JSON.stringify(response)));
            },
        },
    );
}

const fetchNextPageMutation = useQueryNextPage();

// 调用
fetchNextPageMutation.mutate({
    currentPage: (section?.currentPage ?? 1) + 1,
	bookId: section?.id,
});

Q:ListEmptyComponets 不能铺满:

SectionList设置如下属性:

1
2
3
contentContainerStyle={{
  flexGrow: 1,
}}

Q:条件渲染

React 中条件渲染的 N 种方法

在写组件时不要用{ 判断条件 && 组件 }这种写法,因为假如前面的条件是false,那这个结果就是 { false } ,然而这并不是一个合法的组件,在某些场景下会报错。建议使用{ 判断条件 ? 组件 : null }这种方式。

Q: 切圆角时如何把子类超出父视图的部分也切掉?

确保父元素的overflow属性设置为hidden

1
2
3
{
  overflow: "hidden";
}

Q: 如何让文字纵向居中?

  1. View组件包一层
  2. 设置lineHeight与控件高度相同
1
<Text style={{ textAlign: "center", lineHeight: 40 }}>文本内容</Text>

Q: 如何让视图不响应事件?

1
<View pointerEvents="none" />

Q: 有哪些实用API?

 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
28
29
import {
  useWindowDimensions,
  NativeModules,
  StatusBar,
  Platform,
} from "react-native";

const { StatusBarManager } = NativeModules;

const windowWidth = useWindowDimensions().width;
const windowHeight = useWindowDimensions().height;

export const STATUS_BAR_HEIGHT =
  Platform.OS === "android" ? StatusBar.currentHeight : StatusBarManager.HEIGHT;

// Platform.select
const styles = StyleSheet.create({
  container: {
    marginTop: Platform.OS === "android" ? 25 : 0,
  },
  text: {
    ...Platform.select({
      ios: { color: "purple", fontSize: 24 },
      android: { color: "blue", fontSize: 30 },
    }),
    fontWeight: "bold",
    textAlign: "center",
  },
});