React Native

前言: 最近独自上了一个纯前端 RN 的小项目, 项目没有后端, 前端用 RN 做原型, 这个项目后面还要用 RN 做一个大的项目, 所以趁这段时间, 学习整理下 RN 的入门知识, 主要针对从有 React 基础的人.

React-navigator

导航功能: RN:Consider a stack navigator with screens A and B. After navigating to A, its componentDidMount is called. When pushing B, its componentDidMount is also called, but A remains mounted on the stack and its componentWillUnmount is therefore not called. RN forward 的时候等于 push, 不会 unmount stack 上个组件. 但 back 的时候等于 Pop 出去, 是会 unmount 上个的.

stackNavigator

 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
	export const stackNavigationOptions = {
		headerBackTitle: null,
		headerTintColor: 'red',
		headerTitleStyle: {
			fontWeight: 'bold',
			fontSize: 14,
		},
	};
	const SampleStack = createStackNavigator(
		{
			SampleApplyPage: {
				screen: WithSampleContext(SampleApplyPage),
				navigationOptions: {
					...stackNavigationOptions,
					title: 'Urgent Sample',
				},
			},
			SampleConfirmationPage: {
				screen: WithSampleContext(SampleConfirmationPage),
				navigationOptions: {
					...stackNavigationOptions,
					title: 'Sample Confirmation',
				},
			},
		},
		{
			initialRouteName: 'SampleApplyPage',
		},
	);

Flex

container 上的

  • flex-direction: row | row-reverse | column | column-reverse;
  • flex-wrap: nowrap | wrap | wrap-reverse;
  • flex-flow: flex-direction 属性和 flex-wrap 属性的简写形式,默认值为 row nowrap
  • justify-content: 属性定义了项目在主轴上的对齐方式: flex-start | flex-end | center | space-between | space-around

/react-native入门.org_imgs/20190307_210937_IS44dQ.png

  • align-items: 属性定义项目在交叉轴上如何对齐

/react-native入门.org_imgs/20190307_210959_1EInGg.png

  • align-content: 属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

/react-native入门.org_imgs/20190307_211020_dPDdd8.png

item 上的

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self: 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch

auto | flex-start | flex-end | center | baseline | stretch;

flex-grow:

flex-grow 属性定义项目的放大比例,默认为 0,即如果存在剩余空间,也不放大。 如果所有项目的 flex-grow 属性都为 1,则它们将等分剩余空间(如果有的话)。如果一个项目的 flex-grow 属性为 2,其他项目都为 1,则前者占据的剩余空间将比其他项多一倍。

flex-shrink:

flex-shrink 属性定义了项目的缩小比例,默认为 1,即如果空间不足,该项目将缩小。 如果所有项目的 flex-shrink 属性都为 1,当空间不足时,都将等比例缩小。如果一个项目的 flex-shrink 属性为 0,其他项目都为 1,则空间不足时,前者不缩小。 负值对该属性无效。

flex-basis:

flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为 auto,即项目的本来大小。 它可以设为跟 width 或 height 属性一样的值(比如 350px),则项目将占据固定空间。

auto:首先检索该子元素的主尺寸,如果主尺寸不为 auto,则使用值采取主尺寸之值;如果也是 auto,则使用值为 content。

content:指根据该子元素的内容自动布局。有的用户代理没有实现取 content 值,等效的替代方案是 flex-basis 和主尺寸都取 auto。

百分比:根据其包含块(即伸缩父容器)的主尺寸计算。如果包含块的主尺寸未定义(即父容器的主尺寸取决于子元素),则计算结果和设为 auto 一样。

flex

flex: 是 flex-grow、flex-shrink、flex-basis 的缩写. 默认值为 0 1 auto, 后两个属性可选。 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。 建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

  1. 当 flex 取值为一个非负数字,则该数字为 flex-grow 值,flex-shrink 取 1(default),flex-basis 取 0%.
  2. 当 flex 取值为一个长度或百分比,则视为 flex-basis 值,flex-grow 取 1,flex-shrink 取 1(default)
  3. 当 flex 取值为两个非负数字,则分别视为 flex-grow 和 flex-shrink 的值,flex-basis 取 0%
  4. 当 flex 取值为一个非负数字和一个长度或百分比,则分别视为 flex-grow 和 flex-basis 的值,flex-shrink 取 1(default)
1
2
3
4
5
  <div class="parent">
    <div class="item-1"></div>
    <div class="item-2"></div>
    <div class="item-3"></div>
  </div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  .parent {
    display: flex;
    width: 600px;
  }
  .parent > div {
    height: 100px;
  }
  .item-1 {
    width: 140px;
    flex: 2 1 0%; -> 0% width: 140 就会无效
                                   background: blue;
  }
  .item-2 {
    width: 100px;
    flex: 2 1 auto; -> auto width 就是 100px
                    background: darkblue;
  }
  .item-3 {
    flex: 1 1 200px; -> 直接指定 width 就是 200px
                     background: lightblue;
  }

初始宽度是 0 + auto(100) + 200 = 300px 父级宽度是 600px 所以多了 300px, flex-grow 是 2+2+1 所以第份是 60px item1-> 0+ 120 item2-> 100+120 item3-> 200+60

typescript

React 的类型: React.ReactNode, React.ReactElement, React.CSSProperties,

jest

expect 断言

  • common

    1. toBe - toBe 使用 Object.is 来测试是否完全相等
    2. not - 用来测试相反的用例
    3. toEqual - 如果你想检查某个对象的值,请改用 toEqual
    4. toStrictEqual - test that objects have the same types as well as structure.
  • boolean

    1. toBeNull 只匹配 null
    2. toBeUndefined
    3. toBeDefined
    4. toBeTruthy
    5. toBeFalsy
    6. toBeNaN
  • number

    1. toBeGreaterThan
    2. toBeGreaterThanOrEqual
    3. toBeLessThan
    4. toBeLessThanOrEqual
    5. toBeCloseTo
  • regex

    1. toMatch
  • array

    • toHaveLength
    • toContain - 判断数组是否包含特定子项
    • toContainEqual - 判断数组中是否包含一个特定对象
  • object

    1. toMatchObject(Obj) - 判断一个对象嵌套的 key 下面的 value 类型
    2. toHaveProperty(keyPath, value) - 判断在指定的 path 下是否有这个属性
  • customise

    1. expect.extend 将自己的匹配器添加到 Jest.自定义匹配器需要返回一个包含两个 key 的对象
  • error

    1. toThrow - 要测试的特定函数会在调用时抛出一个错误
    2. toThrowError
  • promise

    1. resolves 和 rejects - 用来测试 promise
  • snapshot

    1. toMatchSnapshot - snapshot test
    2. toMatchInlineSnapshot
    3. toThrowErrorMatchingSnapshot
    4. toThrowErrorMatchingInlineSnapshot
  • function

    1. toHaveBeenCalled - 用来判断一个函数是否被调用过
    2. toHaveBeenCalledTimes - 判断函数被调用过几次
    3. lastCalledWith
    4. toBeCalledWith(arg1, arg2, …)
    5. toHaveBeenCalledWith
    6. toHaveBeenLastCalledWith
    7. toHaveBeenNthCalledWith(arg1, arg2, …)
    8. toHaveReturned() - mock function return, ie not throw error
    9. toHaveReturnedTimes(number) - return times
    10. toHaveReturnedWith(value)
    11. toHaveLastReturnedWith(value)
    12. toHaveNthReturnedWith(value)
    13. toBeInstanceOf
  • 构造假对象

    1. expect.anything - expect.anything() matches anything but null or undefined
    2. expect.any(constructor)
    3. expect.arrayContaining(array) - 包含指定数组的任意数组.
    4. expect.not.arrayContaining(array) - 不包含指定数组的任意数组
    5. expect.assertions(number) - 验证有几个断言被执行了.
    6. expect.hasAssertions() - 验证至少有一个断言被执行.
    7. expect.stringContaining(string)
    8. expect.stringMatching(string | regexp)
    9. expect.addSnapshotSerializer() - 自定义序列化工具

mock stub 函数

如何 stub 一个函数?

1
2
3
  jest.spyOn(Math, 'random').mockImplementation(() => 4);

  jest.clearAllMocks(); //clear 掉

api cheetsheat

  1. afterAll(fn, timeout)
  2. afterEach
  3. beforeAll
  4. beforeEach
  5. describe(.only | .skip), fdescribe, xdescribe
  6. describe.each

    1
    2
    3
    4
    5
    6
    7
    8
    
      describe.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])(
        '.add(%i, %i)',
        (a, b, expected) => {
          test(`returns ${expected}`, () => {
            expect(a + b).toBe(expected); 
          });
        },
      );
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
      describe.each`
        a    | b    | expected
        ${1} | ${1} | ${2}
        ${1} | ${2} | ${3}
        ${2} | ${1} | ${3}
      `('returns $expected when $a is added $b', ({a, b, expected}) => {
        test('will be ran', () => {
          expect(a + b).toBe(expected);
        });
      });
  7. test | it (.only |.skip) xtest xit ftest fit
  8. it.each(table)(name, fn, timeout) => name 里

    1
    2
    3
    4
    5
    6
    
      test.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])(
        '.add(%i, %i)',
        (a, b, expected) => {
          expect(a + b).toBe(expected);
        },
      );
  9. test.each`table`(name, fn, timeout)

    1
    2
    3
    4
    5
    6
    7
    8
    
      test.each`
        a    | b    | expected
        ${1} | ${1} | ${2}
        ${1} | ${2} | ${3}
        ${2} | ${1} | ${3}
      `('returns $expected when $a is added $b', ({a, b, expected}) => {
        expect(a + b).toBe(expected);
      });

mock function api

mock function: jest.fn() 就会返回一个 mock function, 默认返回 undefined. /react-native入门.org_imgs/20190319_105552_yqdvHN.png

  • mockClear: Resets all information stored in the mockFn.mock.calls and mockFn.mock.instances arrays.
  • mockReset: mockFn.mockClear() + removes any mocked return values or implementations.
  • mockRestore: mockFn.mockReset() + restores the original (non-mocked) implementation.

jest API

  • genMockFromModule => 相当于 enableAutomock, 然后你可以再自定义一个自己的 mock
  • jest.mock(moduleName, factory?, options?) => doMock() : mock 在 Babel-jest 中有问题, doMock 为了解决这个问题. When using babel-jest, calls to mock will automatically be hoisted to the top of the code block. Use this method if you want to explicitly avoid this behavior.
  • unmock => dontMock 同理.
  • requireActual 和 requireMock, 如果一个 module 中有多个 export, 可以用这个来表明你想用的是 mock 的还是真实的.
  • spyOn: 不仅像fn一样创建一个mock fn, 还会 tracks calls to object[methodName].
  • clearAllMocks() = mockClear()
  • resetAllMocks = mockReset

timer 是给setTimeout, setInterval, clearTimeout, clearInterval, nextTick, setImmediate and clearImmediate这些fn用的.