ReactNative에 기여 해보십시오. Part1

13161 단어 iOSOSSreactnative

이번에 도전한 이슈



htps : // 기주 b. 코m/후세보 k/레아 ct-나치ゔぇ/이스에 s/20627

react-native 의 v0.56.0v0.55.4 로, padding 를 퍼센트 지정하면 잘 스타일링되지 않는다. 라는 것.

우선 재현



실제로 어떤 느낌이 되는지, Description에 실려 있는 코드를 수중에서 재현한다.
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View
} from 'react-native';

export default class App extends Component {
    render() {
        return (
            <View style={{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center',
                backgroundColor: '#F5FCFF',
            }}>
                <View style={styles.testStyle}>
                    <View style={{flex:1, backgroundColor:'red'}}>
                        <Text>内容</Text>
                    </View>
                </View>
            </View>

        );
    }
}


const styles = StyleSheet.create({
    testStyle: {
        width:100,
        height:100,
        backgroundColor: 'blue',
        padding:'5%',
        alignItems: 'center'
    },
});

확실히,



description과 같게 된다. padding5%라면 더 스페이싱이 좁을 것이지만, 조금 넓다. 게다가 본래라면 붉은 박스가 아래까지 늘어날 것이지만, 도중에 끊어져 버리고 있다.

가설



스페이싱 문제와 관련하여. 위의 코드에서는 파란 박스에 padding을 지정하고 있지만, 원래 스페이싱의 계산이 이 파란 박스가 기준이 되어 있지 않다는 가설을 세웠다.

상자가 아래로까지 성장하지 않는 문제는 또한 나중에 기사에서 고려한다.

디버깅 해보세요.



React에서는 모든 컴퍼넌트에 디폴트로 onLayout props를 지정할 수 있다. 이 메소드로 컴퍼넌트의 좌표나 렌더링 정보등을 취득할 수 있으므로, 확실히 올바른 값으로 스페이싱이 계산되고 있는지를 조사해 본다.
...
      <View style={{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
      }}
      onLayout={(e) => {console.log("A", e.nativeEvent.layout)}}
      >
      <View
        style={styles.testStyle}
        onLayout={(e) => {console.log("B", e.nativeEvent.layout)}}
      >
            <View
              style={{flex:1, backgroundColor:'red'}}
              onLayout={(e) => {console.log("C", e.nativeEvent.layout)}}
            >
                <Text>内容</Text>
            </View>
        </View>
    </View>
...
const styles = StyleSheet.create({
    testStyle: {
        width:100,
        height:100,
        backgroundColor: 'blue',
        padding:'5%',
        alignItems: 'center'
    },
});

그러면 콘솔 출력 결과는 다음과 같이 되었다.
C {y: 19, width: 27, x: 36.5, height: 33}
A {y: 0, width: 375, x: 0, height: 667}
B {y: 283.5, width: 100, x: 137.5, height: 100}

이 때, X와 Y의 위치는 부모 요소를 기준으로 한 상대 위치로 표현된다.
B의 높이가 100px이므로, 본래라면 C.y의 좌표는 본래라면 19 는 아니고 5 이 될 것이지만 이 결과는 이상하다. 여러가지 시도한 후, 여기의 스페이싱은 박스의 크기가 아니고, 디바이스의 가로폭을 기준으로 계산되어 있는 것을 알 수 있었다.

이것은 ReactNative의 문제라고 하는지, 렌더링 엔진의 계산의 버그 같은 느낌인 것처럼, ReactNative의 렌더링 엔진인 요가 의 내부 사양을 조사해 보았다.

깊어 보면,



padding 등의 계산을 하고 있는 yoga의 해당 부분의 처리를 찾아보면
그것 같은 것을 발견했다.

htps : // 기주 b. 코 m/후세보오 k/요가/bぉb/마s r/요가/요가. cp#L1097-L1104
...
 static inline float YGNodePaddingAndBorderForAxis( 
     const YGNodeRef node, 
     const YGFlexDirection axis, 
     const float widthSize) { 
   return YGUnwrapFloatOptional( 
       node->getLeadingPaddingAndBorder(axis, widthSize)
       node->getTrailingPaddingAndBorder(axis, widthSize)); 
 } 
...

디바이스의 가로폭을 기준으로 계산되고 있다는 것은, 제3 인수의 widthSize가 이상한 것은 아니다. 그래서 Xcode에서 이 메서드의 Caller(호출원)를 조사해 가서 시험에 widthSize에 100 라고 지정해 앱을 다시 로드해 보면 스페이싱이 바뀌었다. 스쿠쇼를 취해 Photoshop에서 스페이싱을 측정해 보면 훌륭하게 padding이 파란 박스의 높이 100px의 5%의 값(5px)이 되어 있었다. 그래서 이 이슈는 Yoga Engine의 문제라는 것을 확인할 수 있었다.

Part 1은 여기까지.

좋은 웹페이지 즐겨찾기