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
  • align-items: 属性定义项目在交叉轴上如何对齐
  • align-content: 属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

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.

  • 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用的.