mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-05-13 10:07:33 +08:00
[change] export or replace react-dom methods
This change adds the react-dom methods to the main export, since this is a Web-only environment (React Native does something similar). It augments the default render methods in order to move style sheet management under the control of the library (necessary for code-splitting support). Relates to #52
This commit is contained in:
22
README.md
22
README.md
@@ -32,8 +32,9 @@ npm install --save react react-dom react-native-web
|
||||
|
||||
## Example
|
||||
|
||||
React Native for Web exports its components and a reference to the `React`
|
||||
installation. Styles are defined with, and used as JavaScript objects.
|
||||
React Native for Web exports its components, a reference to the `react`
|
||||
installation, and the `react-dom` methods (customized for Web). Styles are defined
|
||||
with, and used as JavaScript objects.
|
||||
|
||||
Component:
|
||||
|
||||
@@ -87,22 +88,20 @@ const styles = StyleSheet.create({
|
||||
})
|
||||
```
|
||||
|
||||
Pre-render styles on the server:
|
||||
Pre-rendering on the server automatically includes your app styles:
|
||||
|
||||
```js
|
||||
// server.js
|
||||
import App from './components/App'
|
||||
import React, { StyleSheet } from 'react-native-web'
|
||||
import React from 'react-native-web'
|
||||
|
||||
const html = React.renderToString(<App />);
|
||||
const css = StyleSheet.renderToString();
|
||||
|
||||
const Html = () => (
|
||||
<html>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta content="initial-scale=1,width=device-width" name="viewport" />
|
||||
<style id="react-stylesheet" dangerouslySetInnerHTML={{ __html: css } />
|
||||
</head>
|
||||
<body>
|
||||
<div id="react-root" dangerouslySetInnerHTML={{ __html: html }} />
|
||||
@@ -111,19 +110,14 @@ const Html = () => (
|
||||
)
|
||||
```
|
||||
|
||||
Render styles on the client:
|
||||
Rendering on the client automatically includes your app styles:
|
||||
|
||||
```js
|
||||
// client.js
|
||||
import App from './components/App'
|
||||
import React, { StyleSheet } from 'react-native-web'
|
||||
import ReactDOM from 'react-dom'
|
||||
import React from 'react-native-web'
|
||||
|
||||
const reactRoot = document.getElementById('react-root')
|
||||
const reactStyleSheet = document.getElementById('react-stylesheet')
|
||||
|
||||
ReactDOM.render(<App />, reactRoot)
|
||||
reactStyleSheet.textContent = StyleSheet.renderToString()
|
||||
React.render(<App />, document.getElementById('react-root'))
|
||||
```
|
||||
|
||||
## APIs
|
||||
|
||||
@@ -7,7 +7,8 @@ module.exports = {
|
||||
},
|
||||
externals: [{
|
||||
'react': true,
|
||||
'react-dom': true
|
||||
'react-dom': true,
|
||||
'react-dom/server': true
|
||||
}],
|
||||
output: {
|
||||
filename: 'react-native-web.js',
|
||||
|
||||
@@ -2,7 +2,5 @@
|
||||
<meta charset="utf-8">
|
||||
<title>React Native for Web</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="The core React Native components adapted and expanded upon for the web">
|
||||
<style id="react-stylesheet"></style>
|
||||
<div id="react-root"></div>
|
||||
<script src="/examples.js"></script>
|
||||
|
||||
@@ -2,8 +2,7 @@ import { MediaProvider, matchMedia } from 'react-media-queries'
|
||||
import App from './components/App'
|
||||
import createGetter from 'react-media-queries/lib/createMediaQueryGetter'
|
||||
import createListener from 'react-media-queries/lib/createMediaQueryListener'
|
||||
import React, { StyleSheet } from '../src'
|
||||
import ReactDOM from 'react-dom'
|
||||
import React from '../src'
|
||||
|
||||
const mediaQueries = {
|
||||
small: '(min-width: 300px)',
|
||||
@@ -12,11 +11,9 @@ const mediaQueries = {
|
||||
}
|
||||
const ResponsiveApp = matchMedia()(App)
|
||||
|
||||
ReactDOM.render(
|
||||
React.render(
|
||||
<MediaProvider getMedia={createGetter(mediaQueries)} listener={createListener(mediaQueries)}>
|
||||
<ResponsiveApp />
|
||||
</MediaProvider>,
|
||||
document.getElementById('react-root')
|
||||
)
|
||||
|
||||
document.getElementById('react-stylesheet').textContent = StyleSheet.renderToString()
|
||||
|
||||
54
src/__tests__/index-test.js
Normal file
54
src/__tests__/index-test.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/* eslint-env mocha */
|
||||
|
||||
import * as utils from '../modules/specHelpers'
|
||||
import assert from 'assert'
|
||||
import React from '..'
|
||||
|
||||
suite('ReactNativeWeb', () => {
|
||||
suite('exports', () => {
|
||||
test('React', () => {
|
||||
assert.ok(React)
|
||||
})
|
||||
|
||||
test('ReactDOM methods', () => {
|
||||
assert.ok(React.findDOMNode)
|
||||
assert.ok(React.render)
|
||||
assert.ok(React.unmountComponentAtNode)
|
||||
})
|
||||
|
||||
test('ReactDOM/server methods', () => {
|
||||
assert.ok(React.renderToString)
|
||||
assert.ok(React.renderToStaticMarkup)
|
||||
})
|
||||
})
|
||||
|
||||
suite('render methods', () => {
|
||||
const id = 'test'
|
||||
let div
|
||||
|
||||
setup(() => {
|
||||
div = document.createElement('div')
|
||||
div.id = id
|
||||
document.body.appendChild(div)
|
||||
})
|
||||
|
||||
teardown(() => {
|
||||
document.body.removeChild(div)
|
||||
})
|
||||
|
||||
test('"render" creates style sheet', () => {
|
||||
React.render(<div />, div)
|
||||
assert.ok(document.getElementById('react-stylesheet'))
|
||||
})
|
||||
|
||||
test('"renderToString" creates style sheet', () => {
|
||||
const result = React.renderToString(<div />)
|
||||
assert.ok(result.indexOf('react-stylesheet') > -1)
|
||||
})
|
||||
|
||||
test('"renderToStaticMarkup" creates style sheet', () => {
|
||||
const result = React.renderToStaticMarkup(<div />)
|
||||
assert.ok(result.indexOf('react-stylesheet') > -1)
|
||||
})
|
||||
})
|
||||
})
|
||||
41
src/index.js
41
src/index.js
@@ -1,5 +1,8 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
|
||||
// api
|
||||
import StyleSheet from './modules/StyleSheet'
|
||||
|
||||
// components
|
||||
@@ -11,7 +14,35 @@ import TextInput from './components/TextInput'
|
||||
import Touchable from './components/Touchable'
|
||||
import View from './components/View'
|
||||
|
||||
const renderStyle = () => {
|
||||
return `<style id='react-stylesheet'>${StyleSheet.renderToString()}</style>`
|
||||
}
|
||||
|
||||
const render = (element, container, callback) => {
|
||||
const styleElement = document.getElementById('react-stylesheet')
|
||||
if (!styleElement) {
|
||||
const style = renderStyle()
|
||||
container.insertAdjacentHTML('beforebegin', style)
|
||||
}
|
||||
return ReactDOM.render(element, container, callback)
|
||||
}
|
||||
|
||||
const renderToString = (element) => {
|
||||
const style = renderStyle()
|
||||
const html = ReactDOMServer.renderToString(element)
|
||||
return `${style}\n${html}`
|
||||
}
|
||||
|
||||
const renderToStaticMarkup = (element) => {
|
||||
const style = renderStyle()
|
||||
const html = ReactDOMServer.renderToStaticMarkup(element)
|
||||
return `${style}\n${html}`
|
||||
}
|
||||
|
||||
const ReactNative = {
|
||||
// apis
|
||||
StyleSheet,
|
||||
|
||||
// components
|
||||
Image,
|
||||
ListView,
|
||||
@@ -21,11 +52,13 @@ const ReactNative = {
|
||||
Touchable,
|
||||
View,
|
||||
|
||||
// apis
|
||||
StyleSheet,
|
||||
|
||||
// React
|
||||
...React
|
||||
...React,
|
||||
...ReactDOM,
|
||||
...ReactDOMServer,
|
||||
render,
|
||||
renderToString,
|
||||
renderToStaticMarkup
|
||||
}
|
||||
|
||||
module.exports = ReactNative
|
||||
|
||||
Reference in New Issue
Block a user