2017-06-27 2 views
0

Ich möchte etwas wie SCSS für React Native schreiben: Es wird Ihre Komponente Jsx und die speziellen SCSS-like Stile analysieren und eine normale RN-Komponente mit überarbeiteten Stilen und Jsx zurückgeben.Wie extrahiert man JSX aus der Klassen-Render-Methode?

Können sagen, wir haben diesen Code reagieren:

class MyClass extends Component { 
    render() { 
    return (
     <View style={styles.container}> 
     <Text>I remember syrup sandwiches</Text> 
     </View> 
    ); 
    } 
} 

Auch ich habe SCSS-ish Stile, wo jede Text-Komponente innerhalb der übergeordneten mit einem Behälter „Klasse“ die gleichen Requisiten, die wir zur Verfügung gestellt.

const styles = StyleSheet.create(
    toRNStyles({ 
    container: { 
     Text: { color: 'red' }, 
    }, 
    }) 
); 

Am Ende müssen wir die Ausgabe von so etwas wie folgt aus:

... 
<View style={styles.container}> 
    <Text style={styles._Text_container}> 
    I remember syrup sandwiches 
    </Text> 
</View> 
... 

So wie kann ich die jsx erhalten, die von außerhalb der Klasse von der Render-Methode ist der Rückkehr?

+0

Zu welchem ​​Zweck benötigen Sie den Ausgang? Sie könnten 'render()' wie von @yoda vorgeschlagen verwenden oder die Komponente mit einer Komponente höherer Ordnung umschließen, wenn Sie zur Laufzeit angepasst werden müssen. Die Ausgabe ist nicht JSX (die Syntax für die Verwendung von Komponenten), sondern ein React-Element (ein Objekt, das die Instanz einer Komponente beschreibt). – ryanjduffy

+0

Warum möchten Sie das tun? Stellen Sie einen Kontext bereit. Wahrscheinlich ist das nicht das, was Sie tun wollen, um Ihr Problem zu lösen. – trixn

+2

[Das XY-Problem] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) –

Antwort

0

Sie könnten ein Plugin für babel schreiben, da reactive-native es verwendet, um JSX in plain javascript umzuwandeln. Werfen Sie einen Blick auf die folgenden Pakete:

  • babel-Helfer-Builder-reagieren-jsx
  • babel-Plugin-Syntax-jsx
  • babel-Plugin-Transformations-reagieren-jsx
  • babel -plugin transformations reagieren-jsx-Quelle
  • jsx-ast-utils
0

Es scheint nicht ein Standard-Weg, dies zu tun zu sein. Sie könnten jedoch ReactDOMServer importieren und seine renderToStaticMarkup-Funktion verwenden.

So:

class MyApp extends React.Component { 
 
    render() { 
 
    var myTestComponent = <Test>bar</Test>; 
 
    console.dir(ReactDOMServer.renderToStaticMarkup(myTestComponent)); 
 
    
 
    return myTestComponent; 
 
    } 
 
} 
 

 
const Test = (props) => { 
 
    return (
 
    <div> 
 
     <p>foo</p> 
 
     <span>{props.children}</span> 
 
    </div> 
 
); 
 
} 
 

 
ReactDOM.render(<MyApp />, document.getElementById("myApp"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom-server.js"></script> 
 
<div id="myApp"></div>

0

Ich denke, das zurückgegebene Element Parsen der falsche Ansatz ist. Eine Herausforderung wird sein, dass der Wert style ein Objekt ist (styles.container === ein Hash von Stil Schlüssel/Werte), während Sie einen Schlüssel benötigen, der dem Objekt zugeordnet werden kann.

Ich denke, der am meisten wiederverwendbare Ansatz besteht darin, den React-Kontext (den ich annehme, dass RN unterstützt!) Zu erstellen styleName, die erweitert werden kann, wie Sie den Komponentenbaum heruntergekommen.

Hier ist ein erster Ansatz, der ein paar Annahmen macht (z. B. dass jede Komponente styleName als Requisite zur Verfügung gestellt hat; Sie sollten dies zur Entwurfszeit und nicht zur Laufzeit bereitstellen). Kurz gesagt, Sie wickeln jede Komponente, die Sie teilnehmen möchten, mit dieser HOC und die Bereitstellung styleName als eine Stütze für jede Komponente. Diese styleName Werte werden verkettet, um kontextualisierte Namen zu erzeugen, die Stilen zugeordnet sind.

Dieses Beispiel erzeugt:

<div style="background-color: green; color: red;"> 
    <div style="color: blue;">Some Text</div> 
</div> 

const CascadingStyle = (styles, Wrapped) => class extends React.Component { 
 
    static displayName = 'CascadingStyle'; 
 
    
 
    static contextTypes = { 
 
    styleName: React.PropTypes.string 
 
    } 
 
    
 
    static childContextTypes = { 
 
    styleName: React.PropTypes.string 
 
    } 
 
    
 
    // pass the current styleName down the component tree 
 
    // to other instances of CascadingStyle 
 
    getChildContext() { 
 
    return { 
 
     styleName: this.getStyleName() 
 
    }; 
 
    } 
 

 
    // generate the current style name by either using the 
 
    // value from context, joining the context value with 
 
    // the current value, or using the current value (in 
 
    // that order). 
 
    getStyleName() { 
 
    const {styleName: contextStyleName} = this.context; 
 
    const {styleName: propsStyleName} = this.props; 
 
    let styleName = contextStyleName; 
 

 
    if (propsStyleName && contextStyleName) { 
 
     styleName = `${contextStyleName}_${propsStyleName}`; 
 
    } else if (propsStyleName) { 
 
     styleName = propsStyleName; 
 
    } 
 

 
    return styleName; 
 
    } 
 
    
 
    // if the component has styleName, find that style object and merge it with other run-time styles 
 
    getStyle() { 
 
    if (this.props.styleName) { 
 
     return Object.assign({}, styles[this.getStyleName()], this.props.styles); 
 
    } 
 

 
    return this.props.styles; 
 
    } 
 
    
 
    render() { 
 
    return (
 
     <Wrapped {...this.props} style={this.getStyle()} /> 
 
    ); 
 
    } 
 
}; 
 

 
const myStyles = { 
 
    container: {backgroundColor: 'green', color: 'red'}, 
 
    container_text: {color: 'blue'} 
 
}; 
 

 
const Container = CascadingStyle(myStyles, (props) => { 
 
    return (
 
    <div {...props} /> 
 
); 
 
}); 
 

 
const Text = CascadingStyle(myStyles, (props) => { 
 
    return (
 
    <div {...props} /> 
 
); 
 
}); 
 

 
const Component =() => { 
 
    return (
 
    <Container styleName="container"> 
 
     <Text styleName="text">Some Text</Text> 
 
    </Container> 
 
); 
 
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Verwandte Themen